2013-11-21 1 views
1

Это очень простое регулярное выражение, тем не менее, он работает в течение более 30 секунд на очень короткую строку: (i7 3970k @ 3.4ghz)Java Сличитель медленно регулярное выражение

Pattern compile = Pattern.compile("^(?=[a-z0-9-]{1,63})([a-z0-9]+[-]{0,1}){1,63}[a-z0-9]{1}$"); 
Matcher matcher = compile.matcher("test-metareg-rw40lntknahvpseba32cßáàâåäæç.nl"); 
boolean matches = matcher.matches(); //Takes 30+ seconds 

первой частью (? =) Является утверждением о том, что строка содержит в макс эти символы

2-ая часть утверждение о том, что строка не превышает синтаксис, например, на этом случае, чтобы предотвратить - 's и конец, по крайней мере в [а-z0-9]

+0

установлено, что:) ... –

+0

Рассматривая ваше регулярное выражение, возможно, вам нужно/нужно проанализировать строку вручную. –

+0

Чрезмерная учетная запись. Ваше регулярное выражение слишком сложно. Разберите вручную, как сказал @LuiggiMendoza. –

ответ

1

Я пытался угадать ваше намерение, но это было непросто:

(?=[a-z0-9-]{1,63}) этот внешний вид, похоже, требует, чтобы следующее до 63 символов было строчными буквами ASCII или цифрами, но на самом деле это будет успешным, даже если есть только одна буква, за которой следует что-либо. Поэтому, возможно, вы имели в виду (?=[a-z0-9-]{1,63}$), чтобы запретить что-либо еще после законного до 63 символов.

Возможно, вам нужны группы по меньшей мере одной буквы или цифры между -, но вы сделали необязательным необязательное создание ограничения и возможности для многих возможностей, которые создали накладные расходы вашего выражения. Вы можете просто сказать: ([a-z0-9]++-){0,63}[a-z0-9]+. Группы в фигурных скобках требуют, по меньшей мере, одной буквы или номера и требуют минуса после этого, выражение в конце требует по крайней мере одной буквы или номера в конце выражения, но также будет соответствовать последней группе без следующего - на в то же время. Эта последняя группа также может быть единственной, если в вашем тексте не содержится -.

Поместив это все вместе, вы создадите: (?=[a-z0-9-]{1,63}$)([a-z0-9]++-){0,63}[a-z0-9]+. Обратите внимание, что вам не нужен ведущий ^ или задний $, если вы используете метод matches; это уже означает, что границы строк должны соответствовать границам выражений.

Я надеюсь, что я получил ваше намерение правильно ...

+0

Тестирование против нескольких строк сейчас :) –

+0

* ОБНОВЛЕНО * http://pastebin.com/y1fkaZ47 - это то, что я тестировал. Кажется, сейчас прекрасно. Я склоняюсь перед тобой :) –

+0

Принимается как ответ –

0

Я установил это регулярное выражение, заменив его следующим образом:

^(?=[a-z0-9-]{1,63})([a-z0-9]{0,1}|[-]{0,1}){1,63}[a-z0-9]{1}$ 

Раздел ([a-z0-9]+[-]{0,1}){1,63} стал: ([a-z0-9]{0,1}|[-]{0,1}){1,63}

+1

Почему вы пишете '{0,1}' вместо '?' Все время? Вы знаете, что '[a-z0-9] {0,1} | [-] {0,1}' совпадает с '[a-z0-9 -]?' – Holger

+0

'[a-z0-9 ] {0,1} | [-] {0,1} 'совпадает с' [a-z0-9 -]? '. Это не помешает '--'. – Pshemo

+0

Да, я знаю, не знаю точно, почему я это сделал :) –

0
  • Если вы хотите сделать убедитесь, что в вашей строке нет --. Используйте отрицательный взгляд вперед (?!.*--).
  • Также нет смысла писать {1}.
  • Другое дело, если вы хотите, чтобы строка имела максимум 63 символа, тогда вам нужно добавить $ в конец (?=[a-z0-9-]{1,63}$).

Так может быть ^(?=[a-z0-9-]{1,63}$)(?!.*--)[a-z0-9-]+[a-z0-9]$

0

Я думаю, что от того, что вы говорите, ваше регулярное выражение может быть упрощено до этого
Edit - (для потомков) После прочтения @ поста Хольгер, я меняюсь, чтобы это исправить возможные катастрофические откаты , и ускорить его, что, как показывают мои скамейки, возможно, самый быстрый способ сделать это.

# ^(?=[a-z0-9-]{1,63}$)[a-z0-9]++(?:-[a-z0-9]+)*+$ 

^         # BOL 
(?= [a-z0-9-]{1,63} $)    # max 1 - 63 of these characters 
[a-z0-9]++ (?: - [a-z0-9]+)*+  # consume the characters in this order 
$         # EOL 

 Смежные вопросы

  • Нет связанных вопросов^_^