Регулярное выражение: сопоставить все перестановки [дубликаты]

Как упоминалось urschrei, вы должны «векторизовать» чек. Быстрее проверять наличие миллиона элементов один раз (как это делается на C), чем проверять один элемент на миллион раз.

-2
задан Mark 16 January 2019 в 10:15
поделиться

1 ответ

Прямой подход

[abc]{3} будет соответствовать слишком многим результатам, поскольку он также будет соответствовать aab. Чтобы не выполнять двойное совпадение a, вам необходимо удалить a из следующей группы, оставив вас с a[bc]{2}.

a[bc]{2} будет соответствовать слишком много результатов, так как он также будет соответствовать 'abb'. Чтобы не выполнять двойное совпадение b, вам необходимо удалить a из следующей группы, оставив вас с ab[c]{1} или abc для краткости.

abc не будут соответствовать всем комбинациям, поэтому вам понадобится другая группа.

(abc)|([abc]{3}), что снова будет соответствовать слишком много комбинаций.

Этот путь ведет вас вниз по пути перечисления всех перестановок в явном виде в группах.

Можете ли вы создать комбинации, чтобы вам не нужно было записывать все комбинации?

(abc)|(acb) можно записать как a((bc)|(cb)).

(bc)|(cb) Я не могу сократить это дальше.

Совпадение слишком много и удаление ненужных

В зависимости от движка регулярных выражений вы можете выразить AND в качестве заглядывания вперед, чтобы вы могли удалять совпадения. ЭТО, а не ЭТО потребляет ЭТО.

(?=[abc]{3})(?=(?!a.a))[abc]{3} не будет соответствовать ака.

Эта проблема теперь аналогична приведенной выше, где вам нужно удалить все комбинации, которые могут нарушить ваши перестановки. В этом примере это любое выражение, содержащее один и тот же символ несколько раз.

'(.) \ 1+' в этом выражении групповые ссылки используются для собственных совпадений с одним и тем же символом несколько раз, но требуется знание, сколько групп существует в выражении, и оно очень хрупкое. Добавление групп убивает выражение ((.)\1+), больше не совпадает , Относительные обратные ссылки существуют и требуют знания вашего конкретного движка регулярных выражений. \k<-1> может быть то, что вы могли искать. Я предполагаю, что .net, поскольку у меня есть тестер регулярных выражений, добавленный в закладки для этого.

Перестановки, которые я хочу исключить: nn. n.n .nn nnn

Итак, я создаю эти шаблоны: ((?<1>.)\k<1>.) ((?<2>.).\k<2>) (.(?<3>.)\k<3>) ((?<4>.)\k<4>\k<4>) [1142 ]

Собирая все это вместе, я получаю это выражение, обратите внимание, что я использовал относительные обратные ссылки в том виде, в каком они есть в .net - ваш пробег может отличаться.

(?=[abc]{3})(?=(?!((?<1>.)\k<1>.)))(?=(?!((?<2>.).\k<2>)))(?=(?!(.(?<3>.)\k<3>)))(?=(?!((?<4>.)\k<4>\k<4>)))[abc]{3}

Ответ "да" для конкретной длины.

Вот некоторые данные тестирования.

0
ответ дан Johannes 16 January 2019 в 10:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: