Помогите взломать либеральное регулярное выражение URL Грубера
Вопрос
я взял Либеральное регулярное выражение URL от Daring Fireball, объединил его с некоторые улучшения Алана Шторма и исправил некоторые ошибки, такие как поддержка символов IDN внутри круглых скобок.Вот что у меня есть:
/(?:[\w-]+:\/\/?|www[.])[^\s()<>]+(?:(?:\([^\s()<>]*\)[^\s()<>]*)+|[^[:punct:]\s]|\/)/
Однако я столкнулся с ошибкой, которую не могу решить:
'www.dsd(sd)sdsd.com' // can also be the valid 'www.dsd.com/whatever(whatever)'
Указанный выше URL-адрес распознается как www.dsd(sd)sdsd.com'
(или www.dsd.com/whatever(whatever)'
) вместо www.dsd(sd)sdsd.com
(или www.dsd.com/whatever(whatever)
).Кажется, это происходит только тогда, когда URL-адрес содержит круглые скобки, поскольку следующий URL-адрес:
'www.sampleurl.com'
Правильно ли признается www.sampleurl.com
.
Я думаю тот [^[:punct:]\s]|\/
часть регулярного выражения не выполняется, если URL-адрес содержит круглые скобки, Я пытаюсь уже некоторое время, но не могу найти решение.Может кто-нибудь мне помочь?
Для товара я создал Рубулярная постоянная ссылка с регулярным выражением и некоторыми тестовыми данными (последний URL не работает).
Я думаю, что регулярное выражение Грубера было немного поспешным, например, оно не соответствует URL-адресу типа:
http://en.wikipedia.org/wiki/Something_(Special)_For_You
Я еще больше впечатлен, увидев, что оба Грубер и Алан пропустил очень простую опечатку:
\([\w\d]+\)
Не стал бы \(\w+\)
быть достаточным?:С
Решение
Похоже на Грубер пересмотрел свое регулярное выражение:
\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.])(?:[^\s()<>]+|\([^\s()<>]+\))+(?:\([^\s()<>]+\)|[^`!()\[\]{};:'".,<>?«»“”‘’\s]))
Другие советы
www.dsd(sd)sdsd.com не является действительным доменным именем.
Если у тебя есть 'www.dsd.com/whatever(whatever)'
, это будет распознано правильно.(Или, по крайней мере, есть в моих тестах)
/(?:[\w-]+:\/\/?|www[.])[^\s()<>]+(?:(?:\([^\s()<>]*\)[^\s()<>]*)+|[^[:punct:]\s]|\/)/
www. | | |
dsd | |
(sd) |
sdsd.com'
Вот я и думаю, что это сломается...часть регулярного выражения выше (sd)
начинается с экранированной открытой скобки, затем сопоставление класса char sd
, затем экранированная закрывающая скобка, и следующее: [^\s()<>]*
что соответствует sdsd.com'
.