我有一个包含多行文本的文件,我只想匹配那些包含多个单词的行。所有单词都必须出现在该行中,但它们可以以任何顺序出现。
所以如果我们想匹配one , two , three,下面的前 2 行将被匹配:
three one four two <-- match
four two one three <-- match
one two four five
three three three
这可以使用 QRegExp 来完成(无需拆分文本并为每个单词分别测试每一行)吗?
是的,有可能。使用前瞻。这将检查主题字符串的以下部分,而不会实际使用它们。这意味着在前瞻完成后,正则表达式引擎将跳回到它开始的位置,您可以运行另一个前瞻(当然在这种情况下,您从字符串的开头使用它)。试试这个:
^(?=[^\r\n]*one)(?=[^\r\n]*two)(?=[^\r\n]*three)[^\r\n]*$
否定字符类[^\r\n]
确保我们永远不会越过行尾。因为前瞻实际上并没有为匹配消耗任何东西,所以我们[^\r\n]*
在最后(前瞻之后)和$
行尾添加 。事实上,你可以省略$
, 由于 greediness *
,但我认为它使表达式的含义更加明显。
确保将此正则表达式与多行模式一起使用(以便^
与行首$
匹配)。
编辑:
抱歉,QRegExp 显然不支持多行模式m
:
QRegExp 没有与 Perl 的 /m 选项等效的选项,但是可以通过多种方式来模拟,例如通过将输入拆分为行或通过使用搜索换行符的正则表达式进行循环。
它甚至建议将字符串分成几行,这是您要避免的。
由于 QRegExp 也不支持lookbehinds(这将有助于模拟m
),其他解决方案有点棘手。你可以和
(?:^|\r|\n)(?=[^\r\n]*one)(?=[^\r\n]*two)(?=[^\r\n]*three)([^\r\n]*)
那么你想要的那一行应该在 capture group1
中。但我认为将字符串分成几行可能会产生比这更易读的代码。
您可以使用MultilineOption
PatternOption
来自新 Qt5 QRegularExpression的方法,例如:
QRegularExpression("\\w+", QRegularExpression::MultilineOption)