# URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ] # absoluteURI = scheme ":" ( hier_part | opaque_part ) # relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ] # hier_part = ( net_path | abs_path ) [ "?" query ] # opaque_part = uric_no_slash *uric # uric_no_slash = unreserved | escaped | ";" | "?" | ":" | "@" | # "&" | "=" | "+" | "$" | "," # net_path = "//" authority [ abs_path ] # abs_path = "/" path_segments # rel_path = rel_segment [ abs_path ] # rel_segment = 1*( unreserved | escaped | # ";" | "@" | "&" | "=" | "+" | "$" | "," ) # scheme = alpha *( alpha | digit | "+" | "-" | "." ) # authority = server | reg_name # reg_name = 1*( unreserved | escaped | "$" | "," | # ";" | ":" | "@" | "&" | "=" | "+" ) # server = [ [ userinfo "@" ] hostport ] # userinfo = *( unreserved | escaped | # ";" | ":" | "&" | "=" | "+" | "$" | "," ) # hostport = host [ ":" port ] # host = hostname | IPv4address # hostname = *( domainlabel "." ) toplabel [ "." ] # domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum # toplabel = alpha | alpha *( alphanum | "-" ) alphanum # IPv4address = 1*digit "." 1*digit "." 1*digit "." 1*digit # port = *digit # path = [ abs_path | opaque_part ] # path_segments = segment *( "/" segment ) # segment = *pchar *( ";" param ) # param = *pchar # pchar = unreserved | escaped | # ":" | "@" | "&" | "=" | "+" | "$" | "," # query = *uric # fragment = *uric # uric = reserved | unreserved | escaped # reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | # "$" | "," # unreserved = alphanum | mark # mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | # "(" | ")" # escaped = "%" hex hex # hex = digit | "A" | "B" | "C" | "D" | "E" | "F" | # "a" | "b" | "c" | "d" | "e" | "f" # alphanum = alpha | digit # alpha = lowalpha | upalpha # lowalpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | # "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | # "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" # upalpha = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | # "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | # "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" # digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | # "8" | "9" # delim = <>#%" # unwise = {}|\^[]` m{ # scheme [a-zA-Z] ( [a-zA-Z\d+.-] )* : ( # hier_part ( # net_path // # authority ( # server ( ( # userinfo ( [!$&-.:;=\w~] | %[\da-fA-F]{2} )* @ )? # hostport # host ( # hostname ( # domainlabel ( [A-Za-z\d] | [A-Za-z\d] [A-Za-z\d-]* [A-Za-z\d] ) \. )* # toplabel ( [A-Za-z] | [A-Za-z] [A-Za-z\d-]* [A-Za-z\d] ) \.? | # IPv4address \d+ \. \d+ \. \d+ \. \d+ ) ( : # port \d* )? )? | # reg_name ( [!$&-.:;=@\w~] | %[\da-fA-F]{2} )+ ) ( # abs_path ( / # segment ( [!$&-.:=@\w~] | %[\da-fA-F]{2} )* ( ; ( [!$&-.:=@\w~] | %[\da-fA-F]{2} )* )* )+ )? | # abs_path ( / # segment ( [!$&-.:=@\w~] | %[\da-fA-F]{2} )* ( ; ( [!$&-.:=@\w~] | %[\da-fA-F]{2} )* )* )+ ) ( \? # query = uric* ( [!$&-;=?@\w~] | %[\da-fA-F]{2} )* )? | # opaque_part # uric_no_slash ( [!$&-.:;=?@\w~] | %[\da-fA-F]{2} ) # uric* ( [!$&-;=?@\w~] | %[\da-fA-F]{2} )* ) ( \# # fragment = uric* ( [!$&-;=?@\w~] | %[\da-fA-F]{2} )* )? }x; or the shortform ;) m{ [a-z] ( [a-z\d+.-] )* : ((// (((( [!$&-.:;=\w~] | %[\da-f]{2} )* @ )? (( ( [a-z\d] | [a-z\d] [a-z\d-]* [a-z\d] ) \. )* ( [a-z] | [a-z] [a-z\d-]* [a-z\d] ) \.? |\d+ \. \d+ \. \d+ \. \d+ ) ( : \d* )? )? |( [!$&-.:;=@\w~] | %[\da-f]{2} )+ ) ((/ ( [!$&-.:=@\w~] | %[\da-f]{2} )* ( ; ( [!$&-.:=@\w~] | %[\da-f]{2} )* )* )+ )? |(/ ( [!$&-.:=@\w~] | %[\da-f]{2} )* ( ; ( [!$&-.:=@\w~] | %[\da-f]{2} )* )* )+ ) ( \? ( [!$&-;=?@\w~] | %[\da-f]{2} )* )? |(?!/)( [!$&-;=?@\w~] | %[\da-f]{2} )+ ) ( \# ( [!$&-;=?@\w~] | %[\da-f]{2} )* )? }xi;