正则表达式以任意顺序匹配包含两个名称的字符串


179

我需要在正则表达式中进行逻辑与。

就像是

杰克和詹姆斯

同意以下字符串

  • “嗨,杰克,这里是詹姆斯

  • '嗨詹姆斯在这里是杰克 '



@AndersonGreen,该问题过早锁定。由于这些解决方案都不可行,因为多数正则表达式无法识别环视模式量词,因此严重缺乏答案。我认为在问的问题上存在量词
XPMai

Answers:


259

您可以使用环顾四周进行检查:

^(?=.*\bjack\b)(?=.*\bjames\b).*$

测试一下。

这种方法的优点是您可以轻松指定多个条件。

^(?=.*\bjack\b)(?=.*\bjames\b)(?=.*\bjason\b)(?=.*\bjules\b).*$

16
有人介意更详细地说明此示例如何工作吗?
bjmc 2014年

2
vim语法:^\(.*\<jack\>\)\@=\(.*\<james\>\@=\).*$\v^(.*<jack>)@=(.*<james>)@=.*$
mykhal 2014年

有谁知道为什么当我尝试搜索以“#”开头的字符串时(至少在JavaScript中)会中断?^(?=.*\b#friday\b)(?=.*\b#tgif\b).*$无法匹配,blah #tgif blah #friday blah^(?=.*\bfriday\b)(?=.*\btgif\b).*$效果很好。
btleffler

2
这是什么\b意思?
VarunAgw '16


104

尝试:

james.*jack

如果您同时想要两者,则or它们:

james.*jack|jack.*james

1
接受的答案起作用了。这对我来说也很完美。用于在Visual Studio中搜索代码“查找结果”。
智者酸奶

1
这个对我有用,比公认的答案更简洁,更容易理解!
Kumar Manish

1
我需要一个只有两个名称匹配的解决方案,因此对于这种情况,此答案更为简洁。但是接受的答案变得更加简洁,超过2,因为“或”的数量会因数增加。对于3个名称,将有6个“或”,其中4个名称将是24个“或”,等等
WileCau

我建议让它变得懒惰james.*?jack|jack.*?james。这将有助于大文本。
Jekis

42

我要编写的命令说明:-

. 表示任何字符,数字都可以代替。

* 表示零个或多个出现在其之前的事物。

|表示“或”

所以,

james.*jack

将搜索james ,然后输入任意数量的字符,直到jack出现。

既然你想要jack.*james或者james.*jack

因此命令

jack.*james|james.*jack

7
附带说明-您也可以编辑@icyrock的答案(与您六年前的答案相同),您的解释本身非常有用。
WoJ

2
谢谢您提供这个答案,但是我觉得有必要指出,在VSCode搜索中,您的答案 插孔。james。* jack将在'|'之间空格 搜索中要考虑的符号。jack。* james | james。* jack工作并且不寻找空格
jgritten

2
如果$ _explanation ===“很棒”然后返回$ THUMBS_UP ENDIF;
Syed Aqeel


6

你可以做:

\bjack\b.*\bjames\b|\bjames\b.*\bjack\b

2

Vim有一个分支运算符\&,在以任何顺序搜索包含一组单词的行时很有用。而且,扩展所需单词的集合是微不足道的。

例如,

/.*jack\&.*james

将以任意顺序匹配包含jack和的行james

有关用法的更多信息,请参见此答案。我不知道任何其他实现分支的正则表达式。正则表达式 Wikipedia条目上甚至没有记录该运算符。


2

方法1:一个jack和一个james

以防万一,不允许两个jack或两个james,只有一个jack和一个james有效,我们可以设计类似以下的表达式:

^(?!.*\bjack\b.*\bjack\b)(?!.*\bjames\b.*\bjames\b)(?=.*\bjames\b)(?=.*\bjack\b).*$

在这里,我们将使用以下语句排除那些配对实例:

(?!.*\bjack\b.*\bjack\b)

和,

(?!.*\bjames\b.*\bjames\b)

正则演示1

我们也可以简化为

^(?!.*\bjack\b.*\bjack\b|.*\bjames\b.*\bjames\b)(?=.*\bjames\b|.*\bjack\b).*$

RegEx演示2


如果您希望简化/修改/探索该表达式,请在regex101.com的右上方面板中进行说明。如果愿意,您还可以在此链接中观看,它将如何与某些示例输入匹配。


RegEx电路

jex.im可视化正则表达式:

在此处输入图片说明

测试

const regex = /^(?!.*\bjack\b.*\bjack\b|.*\bjames\b.*\bjames\b)(?=.*\bjames\b|.*\bjack\b).*$/gm;
const str = `hi jack here is james
hi james here is jack
hi james jack here is jack james
hi jack james here is james jack
hi jack jack here is jack james
hi james james here is james jack
hi jack jack jack here is james
`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}


方法2:一个jack和一个james按特定顺序

它也可以设计为先james过去jack,类似于以下之一:

^(?!.*\bjack\b.*\bjack\b|.*\bjames\b.*\bjames\b)(?=.*\bjames\b.*\bjack\b).*$

RegEx演示3

反之亦然:

^(?!.*\bjack\b.*\bjack\b|.*\bjames\b.*\bjames\b)(?=.*\bjack\b.*\bjames\b).*$

RegEx演示4


0

您可以使用正则表达式的量词功能,因为lookaround可能并非一直都支持。

(\b(james|jack)\b.*){2,}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.