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

坚强是说给别人听的谎言 提交于 2019-12-17 04:35:11

问题


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.


回答1:


You can use this (see on rubular.com):

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

The first assertion ensures that it's ^[1-4]{4}$, the second assertion is a negative lookahead that ensures that you can't match .*(.).*\1, i.e. a repeated character. The first assertion is "cheaper", so you want to do that first.

References

  • regular-expressions.info/Lookarounds and Backreferences

Related questions

  • How does the regular expression (?<=#)[^#]+(?=#) work?



回答2:


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.




回答3:


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.




回答4:


While the previous answers solve the problem, they aren't as generic as they could be, and don't allow for repetitions in the initial string. For example, {a,a,b,b,c,c}. After asking a similar question on Perl Monks, the following solution was given by Eily:

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

Similarly, this works for longer "symbols" in a string, and for variable length symbols too.



来源:https://stackoverflow.com/questions/3101366/regex-to-match-all-permutations-of-1-2-3-4-without-repetition

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!