Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regex to match all permutations of {1,2,3,4} without repetition

I am implementing the following problem in ruby.

Here's the pattern that I want :

1234, 1324, 1432, 1423, 2341 and so on

i.e. the digits in the four digit number should be between [1-4] and should also be non-repetitive.

to make you understand in a simple manner I take a two digit pattern and the solution should be : 12, 21

i.e. the digits should be either 1 or 2 and should be non-repetitive.

To make sure that they are non-repetitive I want to use $1 for the condition for my second digit but its not working.

Please help me out and thanks in advance.

like image 464
Apoorv Saxena Avatar asked Jun 23 '10 12:06

Apoorv Saxena


People also ask

What does regex 0 * 1 * 0 * 1 * Mean?

Basically (0+1)* mathes any sequence of ones and zeroes. So, in your example (0+1)*1(0+1)* should match any sequence that has 1. It would not match 000 , but it would match 010 , 1 , 111 etc. (0+1) means 0 OR 1.

What does \f mean in regex?

\f stands for form feed, which is a special character used to instruct the printer to start a new page. [*\f]+ Then means any sequence entirely composed of * and form feed, arbitrarily long.

Does empty regex match everything?

An empty regular expression matches everything.

How do I match a pattern in regex?

Regular expressions, called regexes for short, are descriptions for a pattern of text. For example, a \d in a regex stands for a digit character — that is, any single numeral 0 to 9. Following regex is used in Python to match a string of three numbers, a hyphen, three more numbers, another hyphen, and four numbers.


2 Answers

Just for a giggle, here's another option:

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

As each unique character is consumed, the capturing group following it captures an empty string. The backreferences also try to match empty strings, so if one of them doesn't succeed, it can only mean the associated group didn't participate in the match. And that will only happen if string contains at least one duplicate.

This behavior of empty capturing groups and backreferences is not officially supported in any regex flavor, so caveat emptor. But it works in most of them, including Ruby.

like image 121
Alan Moore Avatar answered Sep 28 '22 08:09

Alan Moore


I think this solution is a bit simpler

^(?:([1-4])(?!.*\1)){4}$

See it here on Rubular

^                  # matches the start of the string
    (?:            # open a non capturing group 
        ([1-4])    # The characters that are allowed the found char is captured in group 1
        (?!.*\1)   # That character is matched only if it does not occur once more
    ){4}           # Defines the amount of characters
$

(?!.*\1) is a lookahead assertion, to ensure the character is not repeated.

^ and $ are anchors to match the start and the end of the string.

like image 31
stema Avatar answered Sep 28 '22 07:09

stema