Почему проверка этой строки с помощью Regex.IsMatch приводит к тому, что процессор достигает 100%?
При использовании Regex.IsMatch
(С#,.Net 4.5) на определенной строке ЦП достигает 100%.
Строка:
https://www.facebook.com/CashKingPirates/photos/a.197028616990372.62904.196982426994991/1186500984709792/?type=1&permPage=1
шаблон:
^http(s)?://([\w-]+.)+[\w-]+(/[\w- ./?%&=])?$
Полный код:
Regex.IsMatch("https://www.facebook.com/CashKingPirates/photos/a.197028616990372.62904.196982426994991/1186500984709792/?type=1&permPage=1",
@"^http(s)?://([\w-]+.)+[\w-]+(/[\w- ./?%&=])?$");
Я обнаружил, что изменение URL-адреса предотвращает эту проблему. Измененный URL:
https://www.facebook.com/CashKingPirates/photos/a.197028616990372.62904.196982426994991/1186500984709792
Но все еще очень заинтересовано в понимании того, что вызывает это.
Ответы
Ответ 1
Как указывал nu11p01n73R, у вас есть много обратного отслеживания с вашим регулярным выражением. Это потому, что части вашего выражения могут соответствовать одному и тому же, что дает двигателю множество вариантов, которые он должен попробовать, прежде чем найти результат.
Вы можете избежать этого, изменив регулярное выражение, чтобы сделать отдельные разделы более конкретными. В вашем случае причина состоит в том, что вы хотели бы сопоставить реальную точку, но вместо этого использовали символ совпадения .
. Вам следует избегать этого до \.
.
Это уже должно значительно сократить обратный трафик и сделать его быстрым:
^http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=])?$
И если вы хотите на самом деле сопоставить исходную строку, вам нужно добавить квантификатор в класс символов в конце:
^http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]+)?$
↑
Ответ 2
Я предлагаю вам проверить http://regexr.com/ веб-сайт, чтобы проверить ваше регулярное выражение.
Исправленная версия вашего регулярного выражения такова:
^(https?://(?:[\w]+\.?[\w]+)+[\w]/?)([\w\./]+)(\?[\w-=&%]+)?$
Он также имеет 3 группы:
- group1 = Основной URL (например: facebook.com)
- group2 = Sub urls (например:/CashKingPirates/photos/a.197028616990372.62904.196982426994991/1186500984709792/
- group3 = Переменные (например:? type = 1 & permPage = 1)
Также помните, что для проверки фактического характера точки (.) в вашем регулярном выражении вы должны использовать \. не.
Ответ 3
Ваше регулярное выражение страдает от catastrophic backtracking
. Вы можете просто использовать
^http(s)?://([\w.-])+(/[\w ./?%&=-]+)*$
См. демонстрацию.
https://regex101.com/r/cK4iV0/15