Regex: указанные слова в любом порядке - PullRequest
11 голосов
/ 12 марта 2019

Я плохо разбираюсь в регулярных выражениях, пытаюсь сделать 2 регулярных выражения.

Regex1:

Все указанные слова в любом порядке, но не более того. (репетиция допускается).

Regex2:

Все указанные слова в любом порядке, но не более того. (повторение не допускается).

Слова :

aaa, bbb, ccc

Строки :

aaa ccc bbb
aaa ccc
aaa bbb ddd ccc
bbb aaa bbb ccc

Regex1 Оценить вышеуказанные строки как:

true -> all word present in any order
false -> bbb is missing
false -> unknown word 'ddd'
false -> repetition not allowed

Regex2 оцените вышеуказанные строки как:

true -> all word present in any order
false -> bbb is missing
false -> unknown word 'ddd'
true -> all word present in any order and repetition is allowed

Моя попытка

/^(?=.*\baaa\b)(?=.*\bbbb\b)(?=.*\bccc\b).*$/

Запрашиваемая цель обучения, пожалуйста, уточните.

Ответы [ 4 ]

4 голосов
/ 12 марта 2019

Без повторения regex101

^(?:(aaa|bbb|ccc)(?!.*?\b\1) ?\b){3}$

И с повторением regex101

^(?=.*?\baaa)(?=.*?\bbbb)(?=.*?\bccc)(?:(aaa|bbb|ccc) ?\b)+$

Еще две идеи. Объяснение регулярного выражения в regex101 справа.

3 голосов
/ 12 марта 2019

Для регулярных выражений 1:

var re = /^(?=.*?\baaa\b)(?=.*?\bbbb\b)(?=.*?\bccc\b)\b(?:aaa|bbb|ccc)\b(?: +\b(?:aaa|bbb|ccc)\b)*$/;
var res = document.getElementById('result');
res.innerText += re.test('aaa ccc bbb');
res.innerText += ', ' + re.test('aaa ccc ddd');
res.innerText += ', ' + re.test('aaa ddd bbb');
res.innerText += ', ' + re.test('ccc bbb ccc');
<div id="result"></div>

Ваш код уже выполняет часть уловки.Ваши положительные взгляды проверяют, что все слова появляются где-то, но не то, что они являются единственными присутствующими словами.Чтобы достичь этого, я добавил в начале окружность (^), чтобы определить начало строки.Затем группа без захвата \b(?:aaa|bbb|ccc)\b, чтобы обнаружить первый экземпляр любого слова.Затем следует любое количество слов, перед которыми стоит хотя бы один пробел (?:\s+\b(?:aaa|bbb|ccc)\b)*, в основном тот же шаблон, но с \ s + впереди и заключенный в *.И тогда нам нужно, чтобы строка где-то заканчивалась.Это делается с помощью знака доллара $.

Для регулярного выражения 2:

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

//var re = /^(?=.*?\baaa\b)(?!.*?\baaa\b.*?\baaa\b)(?=.*?\bbbb\b)(?!.*?\bbbb\b.*?\bbbb\b)(?=.*?\bccc\b)(?!.*?\bccc\b.*?\bccc\b)\b(?:aaa|bbb|ccc)\b(?:\s+\b(?:aaa|bbb|ccc)\b)*$/;
// optimized version, see comments
var re = /^(?=.*?\baaa\b)(?=.*?\bbbb\b)(?=.*?\bccc\b)(?!.*?\b(\w+)\b.*?\b\1\b)\b(?:aaa|bbb|ccc)\b(?: +\b(?:aaa|bbb|ccc)\b)*$/;
var res = document.getElementById('result');
res.innerText += re.test('aaa ccc bbb');
res.innerText += ', ' + re.test('aaa ccc ddd');
res.innerText += ', ' + re.test('aaa bbb aaa');
res.innerText += ', ' + re.test('aaa ccc bbb ccc');
<div id="result"></div>

Сначала у нас есть позитивный взгляд (?=.*?\bword\b), чтобы увидеть, что слово существует.Мы следуем этому отрицательному взгляду (?!.*?\baaa\b.*?\baaa\b), чтобы увидеть, что слово не существует несколько раз.Повторите для всех слов.Presto!

Обновление : Вместо того, чтобы проверять, не повторяются ли определенные слова, мы также можем проверить, что НЕТ слово повторяется с помощью конструкции (?!.*?\b(\w+)\b.*?\b\1\b).Это делает регулярное выражение более кратким.Спасибо @revo за указание на это.

2 голосов
/ 12 марта 2019

зачем вам нужно регулярное выражение для выполнения этой функции?Вы можете легко достичь желаемого, сначала разделив строки разделителем ",".Затем вы можете создать объект словаря со словами, которые вы ищете, поскольку ключи и значения по умолчанию равны -1

Регулярное выражение 2 может быть достигнуто путем циклического просмотра входных слов и проверки, существуют ли они как ключи в словареобъект.Регулярное выражение 1 может быть достигнуто аналогичным образом, только когда ключ соответствует входному слову, его значение будет изменено на 1, а при следующем посещении может быть возвращено ложное совпадение.

1 голос
/ 12 марта 2019

Не используйте регулярные выражения для уникальности.

Но для отдельных слов в регулярном выражении вы можете использовать \b

Пример: /\b(word1|word2|word3)\b/

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