Regexp匹配至少两个不同的黑名单词

时间:2014-03-05 20:19:00

标签: regex language-agnostic

这是Regular expression which matches at least two words from a list的后续行动:

如何编写一个与列表中至少两个不同字匹配的正则表达式?

例如,根据列表"foo""bar""baz",我希望正则表达式匹配"foo..bar"但不匹配"foo..foo"和{{1} }。

就像在原始问题中一样,我想避免在正则表达式中重复单词列表(如果我的黑名单长度为30而不是3,如示例中那样?)

1 个答案:

答案 0 :(得分:2)

如果您使用的正则表达式引擎支持它,您可以使用负前瞻和反向引用来执行此操作:

(foo|bar|baz).*(?!\1)(foo|bar|baz)

(?!\1)表示"未跟随第一个捕获组中的那个"。

为了不重复两次列表,pcre正则表达式引擎提供了不同的语法:

(foo|bar|baz).*(?!\1)(?1)

(foo|bar|baz).*(?!\g{1})\g<1>

(?<list>foo|bar|baz).*(?!\g{list})\g<list>

(?(DEFINE)(?<list>foo|bar|baz))(\g<list>).*(?!\1)\g<list>

使用Ruby:

(foo|bar|baz).*(?!\k<1>)\g<1>

(?<list>foo|bar|baz).*(?!\k<list>)\g<list>

(?<list>foo|bar|baz){0}\g<list>.*(?!\k<list>)\g<list>

但是如果正则表达式引擎没有重用子模式的功能,你可以尝试这种模式(适用于pcre,Python re模块,Java,.NET,Ruby但不能使用Javascript或XRegExp) )

(?:(?!\1)(foo|bar|baz).*){2}

说明:

在开始时(第一次),没有定义捕获组,也没有定义反向引用\1。正则表达式引擎忽略了先行条件(请注意,这意味着正则表达式引擎不会将(?!\1)视为(?!),而是选择跳过测试!)。然后捕获列表中的第一个单词,第二次现在定义了反向引用\1,并且前瞻功能完成了它的工作。

对于R语言,您可以使用参数perl=TRUE使其工作并转义反斜杠(如在Java中):

(?:(?!\\1)(foo|bar|baz).*){2}