Я нашел эту статью чрезвычайно полезной. Огромное спасибо 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, которые были также одиночными линиями, я смог обнаружить масштабирование подавляющего большинства браузеров нажав наше приложение только с несколькими строками кода.
Вложенная группа автоматически не приводит к катастрофическому обратному отскоку. В вашем случае это связано с тем, что ваше регулярное выражение вырождается в классический пример катастрофического обратного отсчета (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'-]
взаимно исключают друг друга - есть только один способ сопоставления любой строки.