RegExp зависает при выполнении в JavaScript [дубликат]

Я нашел эту статью чрезвычайно полезной. Огромное спасибо yonran. Я хотел передать дополнительное обучение, которое я нашел, применяя некоторые методы, которые он предоставил. В FF6 и Chrome 9 была добавлена ​​поддержка мультимедийных запросов от JS, что может значительно упростить подход к мультимедийным запросам, необходимый для определения увеличения FF. См. Документы в MDN здесь . Для моих целей мне нужно было только выяснить, был ли увеличен или увеличен браузер, мне не нужен фактический коэффициент масштабирования. Я смог получить ответ с одной строкой JavaScript:

var isZoomed = window.matchMedia('(max--moz-device-pixel-ratio:0.99), (min--moz-device-pixel-ratio:1.01)').matches;

Объединив это с решениями IE8 + и Webkit, которые были также одиночными линиями, я смог обнаружить масштабирование подавляющего большинства браузеров нажав наше приложение только с несколькими строками кода.

2
задан sln 1 December 2014 в 22:53
поделиться

1 ответ

Объяснение

Вложенная группа автоматически не приводит к катастрофическому обратному отскоку. В вашем случае это связано с тем, что ваше регулярное выражение вырождается в классический пример катастрофического обратного отсчета (a*)*.

Поскольку \s в необязательном в ^([a-zA-Z0-9'-]+\s?)*$, на входе без каких-либо пробелов, но имеет символы вне разрешенных list, регулярное выражение просто вырождается до ^([a-zA-Z0-9'-]+)*$.

Вы также можете думать о расширении исходного регулярного выражения:

[a-zA-Z0-9'-]+\s?[a-zA-Z0-9'-]+\s?[a-zA-Z0-9'-]+\s?[a-zA-Z0-9'-]+\s?...

Поскольку \s является необязательным, мы можем удалите его:

[a-zA-Z0-9'-]+[a-zA-Z0-9'-]+[a-zA-Z0-9'-]+[a-zA-Z0-9'-]+...

И мы получили серию последовательных [a-zA-Z0-9'-]+, которые будут пытаться распространять символы между собой и взорвать сложность.

Решение

Стандартный способ записи регулярного выражения в соответствие с token delimiter token ... delimiter token - token (delimiter token)*. Хотя можно переписать регулярное выражение, не повторять token, я бы рекомендовал против него, так как это сложно сделать правильно. Чтобы избежать повторения, вы можете захотеть создать регулярное выражение путем конкатенации строк.

Следуя рецепту выше:

^[a-zA-Z0-9'-]+(\s[a-zA-Z0-9'-]+)*$

Хотя вы можете видеть повторение в повторении здесь, нет катастрофическое обратное отслеживание, поскольку регулярное выражение может расширяться только до:

[a-zA-Z0-9'-]+\s[a-zA-Z0-9'-]+\s[a-zA-Z0-9'-]+\s[a-zA-Z0-9'-]+...

И \s и [a-zA-Z0-9'-] взаимно исключают друг друга - есть только один способ сопоставления любой строки.

2
ответ дан nhahtdh 22 August 2018 в 07:35
поделиться
  • 1
    Спасибо. Это работает хорошо! Не уверен, почему Struts 2, кажется, позволяет разделить в начале и в конце даже с этим REGEX – Tom 2 December 2014 в 20:37
Другие вопросы по тегам:

Похожие вопросы: