Regexp для парсинга URL по RFC
Не претендуя на истину в последней инстанции, однако, хотелось закрыть для себя этот вопрос на всегда. Частенько в скриптах posh\python и т.п. приходится на входе принимать в качестве параметра строку с URL и быть уверенным что это:
Подсматривая в интернет, получилось написать вот такую "красивую" регулярку, которая входящую строку бъет на следующие группы:
- url (собственно если строка соответствует паттерну url - в этой группе будет отображаться полный url
- scheme - схема URL http:// | ftp:// | anycustomscheme://
- hostname - FQDN
- port
- path
- query
Как работает этот regexp вы можете увидеть ниже
(?<url>(?:(?<scheme>[a-zA-Z]+:\/\/)?(?<hostname>(?:[-a-zA-Z0-9@%_\+~#=]{1,256}\.){1,256}(?:[-a-zA-Z0-9@%_\+~#=]{1,256})))(?::(?<port>[[:digit:]]+))?(?<path>(?:\/[-a-zA-Z0-9!amp;'()*+,\\\/:;=@\[\]._~%]*)*)(?<query>(?:(?:\#|\?)[-a-zA-Z0-9!amp;'()*+,\\\/:;=@\[\]._~]*)*))На Python именованные группы нужно обозначать через символ P, поэтому для Python regex будет выглядеть чуть иначе:
(?P<url>(?:(?P<scheme>[a-zA-Z]+:\/\/)?(?P<hostname>(?:[-a-zA-Z0-9@%_\+~#=]{1,256}\.){1,256}(?:[-a-zA-Z0-9@%_\+~#=]{1,256})))(?::(?P<port>[[:digit:]]+))?(?P<path>(?:\/[-a-zA-Z0-9!amp;'()*+,\\\/:;=@\[\]._~%]*)*)(?P<query>(?:(?:\#|\?)[-a-zA-Z0-9!amp;'()*+,\\\/:;=@\[\]._~]*)*))Ну и пример кода на Powershell:
$URL = "https://vcloud.lab.ihumster.ru/api/query?type=adminOrgVdcStorageProfile"
$URL -match "(?<url>(?:(?<scheme>[a-zA-Z]+:\/\/)?(?<hostname>(?:[-a-zA-Z0-9@%_\+~#=]{1,256}\.){1,256}(?:[-a-zA-Z0-9@%_\+~#=]{1,256})))(?::(?<port>[[:digit:]]+))?(?<path>(?:\/[-a-zA-Z0-9!amp;'()*+,\\\/:;=@\[\]._~%]*)*)(?<query>(?:(?:\#|\?)[-a-zA-Z0-9!amp;'()*+,\\\/:;=@\[\]._~]*)*))"
$Matches
True
Name Value
---- -----
path /api/query
hostname vcloud.lab.ihumster.ru
url https://vcloud.lab.ihumster.ru/api/query?type=adminOrgVdcStorageProfile
scheme https://
query ?type=adminOrgVdcStorageProfile
0 https://vcloud.lab.ihumster.ru/api/query?type=adminOrgVdcStorageProfileОперанд -math возвращает boolean результат соответствия строки в $URL нашему регулярному выражению и если он True, то автопеременная $Matches будет содержать key-value словарь в котором ключами будут имена групп с соответствующими values.
Спасибо что дочитали до конца, надеюсь это будет вам полезно.