一個像樣的正則表達式引擎,你可以利用一個漂亮的絕招:
^ # 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甚至不允許冗長的正則表達式,所以它會變得怪異。
只是作爲一個起點:下面的正則表達式將匹配包含bonus
,days
和28
正好一次字符串,但只允許他們在秩序「bonus
,days
和28
」或「days
,bonus
和28
」。你需要添加其他四個排列組合,以獲得完整的正則表達式(和一個完整的混亂)。以編程方式執行此操作,而不是使用正則表達式。
^(?:(?:(?!bonus|days?|28(?:th)?|twenty-eighth?).)*bonus(?:(?!bonus|days?|28(?:th)?|twenty-eighth?).)*days?(?:(?!bonus|days?|28(?:th)?|twenty-eighth?).)*(?:28(?:th)?|twenty-eighth?)(?:(?!bonus|days?|28(?:th)?|twenty-eighth?).)*|(?:(?!bonus|days?|28(?:th)?|twenty-eighth?).)*days?(?:(?!bonus|days?|28(?:th)?|twenty-eighth?).)*bonus(?:(?!bonus|days?|28(?:th)?|twenty-eighth?).)*(?:28(?:th)?|twenty-eighth?)(?:(?!bonus|days?|28(?:th)?|twenty-eighth?).)*)$
測試它here。你被警告了。
你的正則表達式非常複雜,你需要遵循的規則真的很複雜(你的第一句話是另外的)?你能描述匹配一個字符串的規則是什麼嗎?有機會,這可以做得更簡單,沒有你遇到的重複問題。 –
@pietzcker正則表達式應遵循的規則是:1)匹配任何包含'28','獎勵'和'日'的字符串2)不匹配任何包含任何這些字的字符串不止一次。例如。 '天日紅利'或'紅利紅利' – colio303
另外:哪種正則表現風格?我希望它不是JavaScript,否則我想到的解決方案將無法正常工作... –