QRegExp соответствует строкам, содержащим N слов одновременно, но независимо от порядка (т. Е. Логическое И)

У меня есть файл, содержащий много строк текста, и я хочу сопоставить только те строки, которые содержат несколько слов. Все слова должны присутствовать в линии, но они могут прийти в любом порядке.

Так что, если мы хотим соответствовать один, два, три, первые 2 строки ниже будут сопоставлены:

three one four two <-- match
four two one three <-- match
one two four five
three three three

Можно ли это сделать с помощью QRegExp (не разбивая текст и тестирование каждой строки отдельно для каждого слова)?

4

Решение

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

^(?=[^\r\n]*one)(?=[^\r\n]*two)(?=[^\r\n]*three)[^\r\n]*$

Классы отрицанных персонажей [^\r\n] убедитесь, что мы никогда не сможем заглянуть за конец строки. Поскольку предвидения на самом деле ничего не потребляют для матча, мы добавляем [^\r\n]* в конце (после оглядки) и $ для конца строки. На самом деле, вы могли бы опустить $из-за жадности *, но я думаю, что это делает значение выражения немного более очевидным.

Убедитесь, что вы используете это регулярное выражение в многострочном режиме (чтобы ^ а также $ соответствовать началу строки).

РЕДАКТИРОВАТЬ:

Извините, QRegExp видимо не поддерживает многострочный режим m:

QRegExp не имеет эквивалента параметра Perl / m, но его можно эмулировать различными способами, например, разбивая входные данные на строки или используя цикл с регулярным выражением, которое ищет новые строки.

Он даже рекомендует разбивать строку на строки, чего вы хотите избежать.

Поскольку QRegExp также не поддерживает lookbehinds (что поможет эмуляции m), другие решения немного сложнее. Вы могли бы пойти с

(?:^|\r|\n)(?=[^\r\n]*one)(?=[^\r\n]*two)(?=[^\r\n]*three)([^\r\n]*)

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

2

Другие решения

Вы можете использовать MultilineOption PatternOption из нового Qt5 QRegularExpression лайк:

QRegularExpression("\\w+", QRegularExpression::MultilineOption)
1

По вопросам рекламы [email protected]