正则表达式的AND运算符

78
4个回答

118

无法同时匹配 (?=foo)(?=baz),因为这将需要下一个字符同时是 fb,这是不可能的。

也许你想要的是:

(?=.*foo)(?=.*baz)

这意味着foobaz可以出现在任何地方,不一定按顺序,可能会重叠(尽管在这种情况下字母本身不会重叠)。


我刚刚在 http://regexpal.com/ 上尝试了一下,但是没有成功。也许这是 regexpal 的一个 bug? - user366735
3
正则表达式本身没问题,但在regexpal网站测试它可能不是最好的方式,因为无法直观地看到匹配成功或失败的反馈(这是一种零宽度匹配)。建议改用Javascript控制台进行测试,或者在表达式末尾添加.* - Mark Byers
这在Javascript中肯定有效,但在regexpal.com上无效。 - Matt Dell

27

一个布尔(AND)加通配符搜索的示例,我正在使用它作为javascript自动完成插件:

要匹配的字符串:"my word"

要搜索的字符串:"我正在搜索这段文本中的有趣的单词"

您需要以下正则表达式:/^(?=.*my)(?=.*word).*$/im

解释:

^ 断言位于行首

?= 正向先行断言

.* 匹配任何字符(除了换行符)

()

$ 断言位于行尾

i 修饰符:忽略大小写(不区分 [a-zA-Z] 的大小写)

m 修饰符:多行。导致 ^ 和 $ 匹配每行的开头/结尾(而不仅是整个字符串的开头/结尾)

在此处测试正则表达式:https://regex101.com/r/iS5jJ3/1

因此,您可以创建一个javascript函数:

  1. 替换正则表达式保留字符以避免错误
  2. 在空格处拆分字符串
  3. 封装您的单词在正则表达式组内
  4. 创建正则表达式模式
  5. 执行正则表达式匹配

示例:

function fullTextCompare(myWords, toMatch){
    //Replace regex reserved characters
    myWords=myWords.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
    //Split your string at spaces
    arrWords = myWords.split(" ");
    //Encapsulate your words inside regex groups
    arrWords = arrWords.map(function( n ) {
        return ["(?=.*"+n+")"];
    });
    //Create a regex pattern
    sRegex = new RegExp("^"+arrWords.join("")+".*$","im");
    //Execute the regex match
    return(toMatch.match(sRegex)===null?false:true);
}

//Using it:
console.log(
    fullTextCompare("my word","I'm searching for my funny words inside this text")
);

//Wildcards:
console.log(
    fullTextCompare("y wo","I'm searching for my funny words inside this text")
);


2
也许您正在寻找类似于这样的内容。如果您想要在包含“foo”和“baz”的完整行同时出现时选择该行,此正则表达式将符合要求: .*(foo)+.*(baz)+|.*(baz)+.*(foo)+.*

-1
也许只需要一个OR运算符“|”就足以解决您的问题:
字符串:foo,bar,baz 正则表达式:(foo)|(baz) 结果:["foo", "baz"]

4
这个问题涉及到AND逻辑。使用交替符(|)的OR逻辑也会匹配,即使只有一个或另一个单词存在,这并不是意图 - 必须同时存在两个单词。 - mklement0
@mklement0,你说得完全正确。我只提供了一种可能也有用的替代方案。 - Paulo Alexandre

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