QRegExp匹配包含N个单词的行,但无论顺序如何(即逻辑AND)

时间:2012-12-03 19:50:07

标签: c++ regex qt qregexp

我有一个包含多行文字的文件,我想只匹配那些包含多个单词的行。 该行中的所有字词必须,但可以按任意顺序

因此,如果我们想要匹配一个两个三个,那么下面的前两行将匹配:

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

可以使用QRegExp(不拆分文本并分别测试每个单词的每一行)来完成吗?

2 个答案:

答案 0 :(得分:2)

是的,这是可能的。使用lookahead。这将检查主题字符串的以下部分,而不实际使用它们。这意味着在前瞻完成后,正则表达式引擎将跳回到它开始的位置,你可以运行另一个前瞻(当然在这种情况下,你从字符串的开头使用它)。试试这个:

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

否定的字符类[^\r\n]确保我们永远不会超越行尾。因为前瞻实际上并没有为匹配消耗任何东西,所以我们在末尾(在前瞻之后)添加[^\r\n]*并在行末添加$。事实上,由于$的贪婪,你可以省略*,但我认为它使表达的含义更加明显。

确保将此正则表达式用于多行模式(以便^$匹配行的开头)。

修改

抱歉,QRegExp显然是does not support multi-line mode m

  

QRegExp与Perl的/ m选项没有等效,但可以通过各种方式进行模拟,例如将输入拆分为行或使用搜索换行符的正则表达式循环。

它甚至建议将字符串拆分成行,这是你想要避免的。

由于QRegExp也不支持lookbehinds(这有助于模拟m),因此其他解决方案更棘手。你可以选择

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

然后您想要的线应该在捕获组1。但我认为将字符串拆分成行可能会产生比这更可读的代码。

答案 1 :(得分:1)

您可以使用新Qt5 QRegularExpression中的MultilineOption PatternOption,例如:

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