/
(?# PCRE 8.x )
^
(?<scheme> (?i) [a-z0-9+.-]+ (?-i) )
:
(?:\/\/
(?<authority>
(?<userinfo> (?<username> (?&uriUnreserved)+ ) (?: : (?<password> (?&uriUnreserved)+ )? )? @ )?
(?<host>
| (?'ipv4' (?&_ipv4) )
| \[ (?'ipv6' (?&_ipv6) ) \]
| (?<hostname> (?i) (?: (?&hostLabel) \. )* (?&hostLabel) (?-i) )
)
(?: : (?<port> (?&port_number) ) )?
)
)?
(?# If an authority component is present, then the path component must either be empty or begin with a slash. If an authority component is absent, then the path cannot begin with an empty segment, that is with two slashes as the following characters would be interpreted as an authority component. )
(?# TODO: Exception: file URI scheme RFC 8089 https://en.wikipedia.org/wiki/File_URI_scheme )
(?<path> (?(authority) (?= [\/?#] | $ ) | (?! \/\/ ) ) (?&pathSequence) )
(?: \? (?'query'(?&_query)) )?
(?: \# (?<fragment>(?&_fragment)))?
$
(?(DEFINE)
(?# http://es5.github.io/#A.6 )
(?<uriCharacter> (?&uriReserved) | (?&uriUnescaped) | (?&uriEscaped) )
(?<uriReserved> [;\/?:@&=+$,] )
(?<uriUnescaped> [[:alpha:]\d] | (?&uriMark) )
(?<uriEscaped> %[[:xdigit]]{2} )
(?<uriMark> [-_.!~*`()] )
(?<uriUnreserved> (?&uriUnescaped) | (?&uriEscaped) )
(?# https://en.wikipedia.org/wiki/Uniform_Resource_Identifier )
(?# allowed characters per RFC 952, RFC 1123 )
(?<hostLabel> [a-z0-9-]{1,63} )
(?<_ipv4> (?: (?&octet) \. ){3} (?&octet) )
(?<octet> (?&_250_255) | (?&_200_249) | (?&_0_199) )
(?<_250_255> 25[0-5] )
(?<_200_249> 2[0-4]\d )
(?<_0_199> 1? (?&_0_99) )
(?<_0_99> [1-9]? \d )