Регулярное выражение для соответствия всех перестановок {1,2,3,4} без повторений - PullRequest
10 голосов
/ 23 июня 2010

Я решаю следующую проблему в ruby.

Вот шаблон, который я хочу:

1234, 1324, 1432, 1423, 2341 и т. Д.

т.е. цифры в четырехзначном числе должны быть между [1-4] и также должны быть неповторяющимися.

чтобы вы поняли просто, я беру двузначный шаблон и решение должно быть: 12, 21

т.е.. цифры должны быть 1 или 2 и не должны повторяться.

Чтобы убедиться, что они не повторяются, я хочу использовать $ 1 для условия для моей второй цифры, но оно не работает.

Пожалуйста, помогите мне и спасибо заранее.

Ответы [ 4 ]

22 голосов
/ 23 июня 2010

Вы можете использовать это ( см. На rubular.com ):

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

Первое утверждение гарантирует, что оно ^[1-4]{4}$, второе утверждение является отрицательным прогнозом, который гарантирует, чтоВы не можете сопоставить .*(.).*\1, то есть повторяющийся символ.Первое утверждение «дешевле», поэтому вы хотите сделать это в первую очередь.

Ссылки

Смежные вопросы

11 голосов
/ 23 июня 2010

Просто для смеха, вот еще один вариант:

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

Поскольку каждый уникальный символ используется, группа захвата, следующая за ним, захватывает пустую строку. Обратные ссылки также пытаются сопоставить пустые строки, поэтому, если одна из них не удалась, это может означать, что связанная группа не участвовала в совпадении. И это произойдет, только если строка содержит хотя бы один дубликат.

Такое поведение пустых групп захвата и обратных ссылок официально не поддерживается ни в одном варианте регулярного выражения, поэтому caveat emptor . Но это работает в большинстве из них, включая Ruby.

5 голосов
/ 25 января 2013

Я думаю, что это решение немного проще

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

Посмотрите его здесь на 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) является прогнозным утверждением, чтобы символ не повторялся.

^ и $ - это якоря, соответствующие началу и концу строки.

0 голосов
/ 22 ноября 2018

Хотя предыдущие ответы решают проблему, они не настолько универсальны, как могли бы, и не допускают повторений в исходной строке. Например, {a,a,b,b,c,c}. После аналогичного вопроса на Perl Monks , следующее решение было дано Eily :

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

Аналогично, это работает для более длинных «символов» в строке, а также для символов переменной длины.

...