正则表达式多词搜索

7

我应该使用什么方法在字符串中搜索多个单词?我希望逻辑运算是AND,以便所有单词都出现在字符串中的某个位置。我有一些无意义的段落和一个普通英语段落,我想通过指定一些常见词汇(如“the”和“and”)来缩小范围,但是我希望匹配我指定的所有单词。

5个回答

11

正则表达式支持“lookaround”条件,允许您在字符串中搜索一个术语,然后忘记结果的位置。这将允许在任意顺序下搜索一组单词的字符串。

此功能的正则表达式为:

^(?=.*\bword1\b)(?=.*\bword2\b)(?=.*\bword3\b)

\b 表示单词边界,?= 是环视修饰符。

如果你想要搜索一个可变数量的单词,你需要使用循环构建这个正则表达式字符串 - 只需将每个单词用环视语法包装并附加到表达式中即可。


正是我所需要的。请注意上面缺少了几个星号。每个部分应该是 (?=.*\bword\b) - Tamlyn
星号本来就在那里,但它们被视为标记。我通过应用代码格式进行了修复。 - Alan Moore

5

AND 作为连接符

^(?=.*?\b(?:word1)\b)(?=.*?\b(?:word2)\b)(?=.*?\b(?:word3)\b)

OR作为替代条件

^(?=.*?\b(?:word1|word2|word3)\b
^(?=.*?\b(?:word1)\b)|^(?=.*?\b(?:word2)\b)|^(?=.*?\b(?:word3)\b)

2

首先,我不确定您想要返回什么......整个句子?还是在您给出的两个单词之间的单词?

类似于:

\b(word1|word2)\b(\w+\b)*(word1|word2)\b(\w+\b)*\.

(其中\b是你语言中的单词边界)会匹配包含这两个单词或其中一个单词的完整句子。
你可能需要使其不区分大小写,以便如果它出现在句子开头仍然能匹配。

这不就是匹配包含两个单词的句子吗?可以是word1后跟word2,也可以是word2后跟word1(按需求),或者是word1后跟word1,或者是word2后跟word2(不符合要求)?这就是我在回答问题时遇到的问题类型。 - Jonathan Leffler

2
也许使用语言识别表来识别英语会有效。一些快速测试似乎可以工作(这假设段落仅由换行符分隔)。
正则表达式将匹配其中任何一个条件... \bword\b是被边界分隔的单词,word\b是单词结尾,而just word将在要匹配的段落的任何位置匹配它。
my @paragraphs = split(/\n/,$text);
for my $p (@paragraphs) {
    if ($p =~ m/\bthe\b|\band\b|\ban\b|\bin\b|\bon\b|\bthat\b|\bis\b|\bare\b|th|sh|ough|augh|ing\b|tion\b|ed\b|age\b|’s\b|’ve\b|n’t\b|’d\b/) {
       print "Probable english\n$p\n";
    }
}

我不建议使用“on”来检测英语。在许多斯拉夫语言中,“on”表示“他”(正如我相信Vinko知道的那样 ;))。 - Thomas Bratt
网址已更改:http://en.wikipedia.org/wiki/Wikipedia:Language_recognition_chart#English - Wes P

0
假设使用PCRE(Perl正则表达式),我不确定你是否能够轻松地完成这个任务。AND操作是正则表达式的连接,但你希望能够在单词出现的顺序中进行排列组合,而不必形式上生成排列组合。对于N个单词,当N = 2时,还能接受;当N = 3时,勉强可以;当N > 3时,可能无法接受。因此,简单的迭代解决方案-为每个单词创建一个正则表达式,并确保每个都满足-在我看来似乎是最好的选择。

为什么这N个东西必须是正则表达式呢?在这里可以使用“索引”啊。 - Account deleted
1
\b(foo|bar|baz)\b.*\b(?!\1)(foo|bar|baz)\b.*\b(?!\1)(?!\2)(foo|bar|baz)\b 应该通过使用反向引用和负向前瞻来处理排列,以避免匹配两次相同的单词。它仍然是恶魔般的,但至少模式长度不是O(N!)。 - stevemegson
@BKB:我不确定你所说的使用索引是什么意思。 - Jonathan Leffler
@SteveMegson:是的,我想我知道你在做什么了 - 由于我在学习Perl时还是4.x和5.[0-6]的时代,对于负向先行断言的范围不确定(这是Perl的一个相对较新的功能),所以我在回答中并不武断。正如你所说,这不好,但也不是组合的。 - Jonathan Leffler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接