使用正则表达式以任意顺序显示多个单词

正如标题所说,我需要在一个句子中找到两个特定的单词。但它们可以是任何顺序和任何外壳。如何使用正则表达式执行此操作?

例如,无论单词 test先出现还是 long先出现,我都需要从下面的句子中提取单词 testlong

This is a very long sentence used as a test

更新: 我在第一部分没有提到的是,它也需要不区分大小写。

160548 次浏览

不知道用什么语言

 /test.*long/

或者

/long.*test/

或者

/test/ && /long/

我不认为你可以用一个正则表达式做到这一点。你需要一个 d 的逻辑 AND-1来搜索每个单词。

如果要提取匹配项,请使用捕获组: (test)|(long) 然后根据使用的语言,您可以使用 $1和 $2来引用匹配的组,例如。

试试这个:

/(?i)(?:test.*long|long.*test)/

这将匹配 test,然后 long,或 long,然后 test。它将忽略大小写的差异。

我假设(总是危险的)你想找到完整的单词,所以“测试”会匹配,但“暴躁”不会。因此模式必须搜索单词边界,所以我使用“ b”单词边界模式。

/(?i)(\btest\b.*\blong\b|\blong\b.*\btest\b)/

我将 libpcre 与 C 结合使用,在这里我可以定义标注。它们不仅帮助我轻松地匹配单词,还帮助我匹配任何顺序的子表达式。Regexp 看起来像:

(?C0)(expr1(?C1)|expr2(?C2)|...|exprn(?Cn)){n}

调出函数保证每个子表达式完全匹配一次,比如:

int mycallout(pcre_callout_block *b){
static int subexpr[255];
if(b->callout_number == 0){
//callout (?C0) - clear all counts to 0
memset(&subexpr,'\0',sizeof(subexpr));
return 0;
}else{
//if returns >0, match fails
return subexpr[b->callout_number-1]++;
}
}

类似的事情在 perl 中也应该是可能的。

Vim 有一个分支操作符 \&,当以任意顺序搜索包含任意数量单词的行时,它允许使用更简洁的正则表达式。

比如说,

/.*test\&.*long

将以任意顺序匹配包含 testlong的行。

有关使用的更多信息,请参见 这个答案。我不知道还有其他实现分支的正则表达式; 甚至在 正则表达式维基百科条目中也没有记录操作符。