正则表达式:匹配单词列表而不重用以前匹配的单词

时间:2017-02-22 18:57:46

标签: regex

我正在尝试编写一个正则表达式模式,该模式将匹配包含单词' 28',' bonus'和' day'。

目前我想出了这个:

(bonus|(days|day)|(28th|28)|twenty[ \-\t]*(eighth|eight))[ \ta-z]*(bonus|days|day|(28th|28)|twenty[ \-\t]*(eighth|eight))[ \ta-z]*(bonus|days|day|(28th|28)|twenty[ \-\t]*(eighth|eight))

您可以在此处查看结果:https://regex101.com/r/oOcGqk/8

我遇到的麻烦是任何单词都可以多次使用,但仍然可以匹配。例如:'日奖金','奖励奖金'。如何排除使用这些字词的字符串(' 28','奖励''日期')不止一次?

2 个答案:

答案 0 :(得分:1)

我认为this正则表达式是解决方案:

(?=.*bonus)(?=.*day)(?=.*28|twenty\s*-?\s*eight).*

答案 1 :(得分:1)

使用一个不错的正则表达式引擎,你可以使用一个很好的技巧:

^     # Start of string
(?=(?:(?!bonus).)*bonus()(?:(?!bonus).)*$) 
# Explanation: This lookahead assertion makes sure that "bonus" occurs exactly once 
# in the string. It doesn't actually match any text, it just "looks ahead" to see if 
# that condition is met. However, it contains an empty capturing group "()" that only 
# participates in the match if the lookahead assertion succeeds. We can check this later.
(?=(?:(?!days?).)*days?()(?:(?!days?).)*$)
(?=(?:(?!28(?:th)?|twenty-eighth?).)*(?:28(?:th)?|twenty-eighth?)()(?:(?!28(?:th)?|twenty-eighth?).)*$)
[\w\s]*  # Match a string that only contains alnum character or whitespace
\1\2\3   # Assert that all three words participated in the match
$        # End of string.

您可以测试此here

在JavaScript中,您必须拼出所有可能的排列。不幸的是,JS甚至不允许使用冗长的正则表达式,因此它将是可怕的。

作为一个起点:以下正则表达式将匹配包含bonusdays28的字符串一次,但它只允许按顺序“{{1} },bonusdays“或”28daysbonus“。您需要添加其他四个排列以获得完整的正则表达式(并且完全混乱)。以编程方式执行此操作,而不是使用正则表达式。

28

测试here。你被警告了。