#regex #powershell
Вопрос:
Используя Java, я хочу определить, начинается ли строка со слов и разделителя, а затем «myword», но это регулярное выражение занимает слишком много времени. Что не так ?
^s*(w (s|/|amp;|-)*)*myword
Комментарии:
1. Что вы имеете в виду, говоря » занимает слишком много времени»? Узор слишком длинный? Или требуется много времени, чтобы вернуть результат с каким-то конкретным вводом?
2. В этом примере «Консультант DEPUIS JUILLET 2011 Монреаль» не возвращает никаких результатов ниже 60 секунд
3. Вам нужно
String rx = "^\s*(\w (?:[\s/amp;-] \w )*)[\s/amp;-] myword";
, проверьте ideone.com/CT4ENA4. Спасибо, это работает, но почему этот более эффективен ?
Ответ №1:
Шаблон ^s*(w (s|/|amp;|-)*)*myword
неэффективен из-за вложенного квантора. w
требуется по крайней мере один символ слова и (s|/|amp;|-)*
может совпадать с нулем или более некоторых символов. Когда значение *
применяется к группе, а входная строка не имеет разделителей между символами слов, выражение становится похожим на (w )*
шаблон, который является классическим шаблоном катастрофического возврата.
Просто небольшая иллюстрация w
и (w )*
производительность:
w
: (w )*
Ваш шаблон еще более сложен и привлекает больше тех шагов, которые ведут к отступлению. Чтобы избежать таких проблем, шаблон не должен иметь необязательных подшаблонов внутри количественно определенных групп. То есть создайте группу с обязательными подшаблонами и примените к ней необходимый квантор.
В этом случае вы можете развернуть имеющуюся у вас группу как
String rx = "^\s*(\w (?:[\s/amp;-] \w )*)[\s/amp;-] myword";
Смотрите демонстрацию IDEON
Здесь (w (s|/|amp;|-)*)*
развернуто как (w (?:[s/amp;-] w )*)
(я сохранил внешние скобки для создания группы захвата № 1, вы можете удалить эти скобки, если они вас не интересуют). w
соответствует одному или нескольким словесным символам (поэтому это обязательный подшаблон), а (?:[s/amp;-] w )*
подшаблон соответствует нулю или более ( *
таким образом, вся эта группа необязательна) последовательностям одного или нескольких символов из определенного класса символов [s/amp;-]
(поэтому это обязательно), за которыми следуют один или несколько словесных символов w
.