假设我有一个这样的查询:"one two three",如果我用 |(竖线字符)代替空格,我可以匹配包含其中一个或多个单词的字符串。这就像逻辑OR。
是否有类似的东西可以执行逻辑AND。只要所有单词都存在于字符串中,无论单词顺序如何,都应该匹配。
不幸的是,我离我的“精通正则表达式”书还很远 :(
编辑:我正在使用Javascript,并且查询可以包含任意数量的单词。
假设我有一个这样的查询:"one two three",如果我用 |(竖线字符)代替空格,我可以匹配包含其中一个或多个单词的字符串。这就像逻辑OR。
是否有类似的东西可以执行逻辑AND。只要所有单词都存在于字符串中,无论单词顺序如何,都应该匹配。
不幸的是,我离我的“精通正则表达式”书还很远 :(
编辑:我正在使用Javascript,并且查询可以包含任意数量的单词。
尝试使用前瞻断言:
(?=.*one)(?=.*two)(?=.*three)
但是最好使用三个单独的正则表达式或更简单的字符串搜索操作。
对于这个问题,没有什么好的解决方法。但你可以很容易地匹配任意三个涉及的单词:
(?:\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)
很明显这很糟糕。
长话短说,最好进行三次单独的匹配。
只有在需要按特定顺序找到它们时,才需要将其合并为一次匹配。
如果需要列表中至少包含一个单词,请使用此选项
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
*请注意,您不能将反引号(`)替换为任何其他类型的引号(单引号'或双引号"),否则表达式将失败。