匹配字符串中是否包含所有给定单词的正则表达式

5

假设我有一个这样的查询:"one two three",如果我用 |(竖线字符)代替空格,我可以匹配包含其中一个或多个单词的字符串。这就像逻辑OR。

是否有类似的东西可以执行逻辑AND。只要所有单词都存在于字符串中,无论单词顺序如何,都应该匹配。

不幸的是,我离我的“精通正则表达式”书还很远 :(

编辑:我正在使用Javascript,并且查询可以包含任意数量的单词。

4个回答

7

尝试使用前瞻断言:

(?=.*one)(?=.*two)(?=.*three)

但是最好使用三个单独的正则表达式或更简单的字符串搜索操作。


1
强调“如果能……就更好了”。正则表达式不擅长处理AND操作。 - John Kugelman

2

对于这个问题,没有什么好的解决方法。但你可以很容易地匹配任意三个涉及的单词:

(?:\b(?:one|two|three)\b.*){3}

但是它可以像“一二三”一样轻松匹配“一一一”。

您可以像Gumbo所描述的那样使用前瞻断言。或者您可以编写排列组合,如下所示:

(?\bone\b.*\btwo\b.*\bthree\b|\btwo\b.*\bone\b.*\bthree\b|\bone\b.*\bthree\b.*\btwo\b|\bthree\b.*\bone\b.*\btwo\b|\bthree\b.*\btwo\b.*\bone\b|\btwo\b.*\bthree\b.*\bone\b)

很明显这很糟糕。

长话短说,最好进行三次单独的匹配。


2

进行三次单独匹配。

只有在需要按特定顺序找到它们时,才需要将其合并为一次匹配。


0

如果需要列表中至少包含一个单词,请使用此选项

     let string='One red, two green and 4 orange';
     var words='one two three';
     words=words.split(' ').join('|');
     let pattern=new RegExp(`(?=(.)*?\\b(${words})\\b)((.)+)`,'g');

if(string.match(pattern)!==null){
  //string matches at least one of the words
}else{
  //string does not match any of the words
}

如果需要在您的列表中包含所有单词,请使用此选项

    let string='One red, two green and 4 orange';
     var words='one two three';
     words=words.split(' ').map(function(value,index){return '(?=(.)*?\\b('+value+')\\b)'; }).join('');
     let pattern=new RegExp(`${words}((.)+)`,'g');

if(string.match(pattern)!==null){
  //string matches all words
}else{
  //string does not match all words
}

它是做什么的?首先,它将字符串转换为数组,并将正则表达式连接成其最终形式,然后使用Javascript正则表达式变量插入的魔力。

这将帮助您委派此方法,即使单词列表动态更改也可以轻松应对。

如果您想测试或调整它,可以在此处执行:doregex.com

*请注意,您不能将反引号(`)替换为任何其他类型的引号(单引号'或双引号"),否则表达式将失败。


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