С приличным регулярных выражений, вы могли бы использовать хороший трюк:
^ # 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, иначе решение, о котором я думаю, не будет работать ... –