Regular expression to search for numbers with the same numbers in different order

I have been looking for a regex with Google for an hour or so now and it seems it can't work with this :(

If I have a number, say:

2345

and I want to find any other number with the same numbers, but in a different order, for example:

2345

For example, I map

3245 or 5432 (same numbers, but different order)

How can I write a regex for this?

+2
source share
7 answers

There is an “elegant” way to do this with a single regex:

 ^(?:2()|3()|4()|5()){4}\1\2\3\4$ 

will match the numbers 2, 3, 4 and 5 in any order. All four are required.

Explanation:

(?:2()|3()|4()|5()) corresponds to one of the numbers 2, 3, 4 or 5. The trick now is that the sliding parentheses correspond to the empty line after matching the number (which is always performed).

{4} requires this to be done four times.

\1\2\3\4 , then it is required that all four backlinks participate in the match - what do they do if and only if each number happened once. Since \1\2\3\4 matches an empty string, it will always match as long as the previous condition is true.

For five digits you will need

 ^(?:2()|3()|4()|5()|6()){5}\1\2\3\4\5$ 

etc...

This will work with almost any regular expression except JavaScript.

+16
source

I don't think regex is appropriate. So here is an idea that is faster than regex for this situation:

  • check string lengths, if they are different, return false
  • make a hash from a character (numbers in your case) as integers for counting
  • scroll through the characters of the first line:
    • increment the counter for this character: hash [character] ++
  • iterate over the characters of the second line:
    • decrease the counter for this character: hash [character] -
    • break if any account is negative (or nonexistent)
  • scroll through the entries, making sure each one is 0:
    • if all are 0, return true
    • else return false

EDIT: Java Code (I use Character for this example, not quite Unicode, but this is an idea that matters now):

 import java.util.*; public class Test { public boolean isSimilar(String first, String second) { if(first.length() != second.length()) return false; HashMap<Character, Integer> hash = new HashMap<Character, Integer>(); for(char c : first.toCharArray()) { if(hash.get(c) != null) { int count = hash.get(c); count++; hash.put(c, count); } else { hash.put(c, 1); } } for(char c : second.toCharArray()) { if(hash.get(c) != null) { int count = hash.get(c); count--; if(count < 0) return false; hash.put(c, count); } else { return false; } } for(Integer i : hash.values()) { if(i.intValue()!=0) return false; } return true; } public static void main(String ... args) { //tested to print false System.out.println(new Test().isSimilar("23445", "5432")); //tested to print true System.out.println(new Test().isSimilar("2345", "5432")); } } 

It will also work to compare letters or other sequences of characters such as “god” and “dog”.

+8
source

Put the digits of each number in two arrays, sort the arrays, find out if they contain the same digits with the same indices.

RegExes are not suitable for this task.

+3
source

You can do something like this to provide the correct characters and length

  [2345]{4} 

Ensuring that they exist only once is more difficult and why it is not suitable for regular expressions

 (?=.*2.*)(?=.*3.*)(?=.*4.*)(?=.*5.*)[2345]{4} 
+1
source

The simplest regular expression is just 24 permutations added via the operator or:

/ 2345 | 3245 | 5432 | ... /;

However, you do not want to resolve this with a regular expression if you can handle it. One pass through two numbers as strings is probably better: 1. Check the string length of both strings - if they are different, you are done. 2. Create a hash of all the digits from the number with which you are comparing. 3. Skip the numbers in the number you are checking. If you hit a match in a hash, mark it as used. Continue until you get an unused match in the hash or finish the points.

0
source

I think it’s very easy to achieve if , you’re fine with a match of a number that does not use all the numbers. For instance. if you have number 1234 and you accept a match with number 1111 to return TRUE;

Let me use PHP as an example, since you did not specify which language you are using.

 $my_num = 1245; $my_pattern = '/[' . $my_num . ']{4}/'; // this resolves to pattern: /[1245]{4}/ $my_pattern2 = '/[' . $my_num . ']+/'; // as above but numbers can by of any length $number1 = 4521; $match = preg_match($my_pattern, $number1); // will return TRUE $number2 = 2222444111; $match2 = preg_match($my_pattern2, $number2); // will return TRUE $number3 = 888; $match3 = preg_match($my_pattern, $number3); // will return FALSE $match4 = preg_match($my_pattern2, $number3); // will return FALSE 

Something similar will work in Perl.

0
source

Regular expressions are not suitable for this purpose. Here is the Perl script:

 #/usr/bin/perl use strict; use warnings; my $src = '2345'; my @test = qw( 3245 5432 5542 1234 12345 ); my $canonical = canonicalize( $src ); for my $candidate ( @test ) { next unless $canonical eq canonicalize( $candidate ); print "$src and $candidate consist of the same digits\n"; } sub canonicalize { join '', sort split //, $_[0] } 

Output:

  C: \ Temp> ks
 2345 and 3245 consist of the same digits
 2345 and 5432 consist of the same digits
0
source

All Articles