Регулярное выражение для проверки URL с захватом деталей

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

(?:(?P<scheme>[a-z]*?)://)?(?:(?P<username>.*?):?(?P<password>.*?)[email protected])?(?P<hostname>.*?)/(?:(?:(?P<path>.*?)\?)?(?P<file>.*?\.[a-z]{1,6})?(?:(?:(?P<query>.*?)#?)?(?P<fragment>.*?)?)?)?

однако это не сработает, оно должно соответствовать всем следующим примерам:

http://username:[email protected]/path?arg=value#anchor
http://www.domain.com/
http://www.doamin.co.uk/
http://www.yahoo.com/
http://www.google.au/
https://username:[email protected]/
ftp://user:[email protected]/path/
https://www.blah1.subdoamin.doamin.tld/
domain.tld/# anchor
doamin.tld/? query = 123
domain.co.uk/
domain.tld
http://www.domain.tld/index.php?var1=blah
http://www.domain.tld/path/to/index.ext
почты://[email protected]

и предоставить именованный захват для всех компонентов:

например. http https ftp ftps callto mailto и любой другой, который не указан
имя пользователя
пароль
имя хоста, включая поддомены, domain и tld
путь eg/images/profile/
filename, например file.ext
строка запроса, например.? foo = bar & bar = foo
фрагмент, например. #anchor

Если имя хоста является единственным обязательным полем.

Мы можем предположить, что это происходит из формы, специально запрашивающей URL-адрес, и не будет использоваться для поиска ссылок в тексте.

Ответы

Ответ 1

Измененная версия регулярного выражения mingfai:

/^((?P<scheme>https?|ftp):\/)?\/?((?P<username>.*?)(:(?P<password>.*?)|)@)?(?P<hostname>[^:\/\s]+)(?P<port>:([^\/]*))?(?P<path>(\/\w+)*\/)(?P<filename>[-\w.]+[^#?\s]*)?(?P<query>\?([^#]*))?(?P<fragment>#(.*))?$/

Ответ 2

Можно ли использовать одно регулярное выражение для подкрепления URL-адресов и соответствия всем частям

Нет.

strager regex впечатляет, но в конце концов он менее читабельным, удобным и надежным, чем просто использование подходящего парсера URI. Он обязательно отвергает действительные URI и принимает строки, которые не являются URI, потому что правила форматирования URI не могут быть полностью выражены в регулярном выражении.

электронная почта://[email protected]

В URI mailto не должно быть "//". Вы не можете определить, в каком формате находится остаток (после:) URI будет, пока вы не прочтете схему; многие схемы URI не соответствуют учетным данным @host/path format. Лучше всего принимать только конкретные схемы, где вы знаете, как анализировать свои URI.