Совпадение с точным 3 символом в длине слова 4 со всеми возможными комбинациями - PullRequest
3 голосов
/ 27 апреля 2019

В следующем списке слов

ABCD
AAAA
AAAD
AAAB
BBDA
CCCC
CCCA
DADA
BABC

...
all possible 256 combinations

Используя regrex, я хочу выбрать слова с моим шаблоном, A или B в любой комбинации, охватывающей точно 3 позиции из 4.

Ожидаемый результат:

AAAD
BBDA
BABC

Я знаю, используя [AB] {4} Я могу сопоставить весь мир, но условный поиск с точными 3 позициями из 4 создает путаницу.

Ответы [ 4 ]

4 голосов
/ 27 апреля 2019

Просто перефразируя и подтверждая правила соответствия, которые вы сказали, чтобы мое решение придерживалось его,

  • три позиции из четырех должны занимать либо A, либо B
  • Зарезервирована только одна позиция для C или D

Если это правильно, вы можете использовать это регулярное выражение для сопоставления строк, которые вы хотите.

^(?=[AB]*[CD][AB]*$).{4}$

Объяснение вышеприведенного регулярного выражения:

  • ^ - Начало строки
  • (?=[AB]*[CD][AB]*$) - Положительный взгляд вперед, чтобы обеспечить либо C, либо D появляется в строке только один раз, поэтому остальные три позиции заняты A s и B s
  • .{4}$ - Захват четырех букв A до D с использованием точки, поскольку они уже провереныбыть A до D положительным прогнозом.

Regex Demo

Вот это регулярный график для лучшей визуализации

enter image description here

Редактировать: Подробное объяснение (?=[AB]*[CD][AB]*$)

A положительный взгляд вперед записывается как (?=some regex) и, в отличие от обычного сопоставления и потребления регулярных выражений, обходной путь (положительный / отрицательный взгляд вперед / взгляд назад) просто соответствует символам и не потребляетОни означают, что как только выражение просмотра завершено, маркер регулярного выражения сбрасывается туда, где он был до того, как началось сопоставление.В этом регулярном выражении у нас есть [AB]*[CD][AB]*$ как выражение внутри него, где [AB]* означает, что оно будет соответствовать любому символу в наборе (A или B) ноль или более раз, за ​​которым следует [CD], что означает, что оно должно соответствоватьровно один символ (так как здесь нет квантификатора) из набора символов, который является либо C, либо D, а еще раз [AB]* соответствует любому символу A или B ноль или более раз и, наконец, обеспечивает конец строкидостигается, поскольку оно имеет $.

Таким образом, логическое значение этого выражения состоит в том, что будет точно один случай: C или D, тогда как он может быть окружен As или B с любой стороны, если необходимо, чтобы сформировать четыре алфавита, соответствующих всем комбинациям из четырех букв, имеющих только одно вхождение C или D.

Кроме того, включено предложение revo где [A-D] можно изменить только на . Большое спасибо Revo.

2 голосов
/ 27 апреля 2019

Попробуйте следующее регулярное выражение:

^([^AB\r\n]*[AB]){3}(?!(?1)).*$

Смотрите демо здесь

Если рекурсии ((?1) кластер) не поддерживаются в движке, с которым вы работаете, используйте вместо этого:

^(?:[^AB\r\n]*[AB]){3}(?![^AB\r\n]*[AB]).*$

Смотрите демо здесь

2 голосов
/ 27 апреля 2019

Если я правильно понял, вы хотите сопоставить все строки, которые имеют ровно три символа, либо A, либо B.Это означает, что строка будет иметь ровно один символ, который не является A или B.

. Это можно сделать, заменив все символы As и B в строке и проверив, является ли оставшаяся строка толькоодин символ:

for string in all_your_strings:
    if len(re.sub(r"[AB]", "", string)) == 1:
        # match!
    else:
        # not match
2 голосов
/ 27 апреля 2019

Это будет делать:

^([^AB][AB]{3}|[AB][^AB][AB]{2}|[AB]{2}[^AB][AB]|[AB]{3}[^AB])$

image

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...