const regex = /
# allow multiple groups with the same name
(?J)
# protocol user host-ip port path path path querystring fragment
^
#protocol
(?:(?<scheme>[a-zA-Z][a-zA-Z\d+-.]*):)?
(?|
#slash-slash
\/\/
#userinfo
(?:
#user
(?<user>[a-zA-Z\d\-._~\!$&'()*+,;=%]*)
#password
(?::(?<pass>[a-zA-Z\d\-._~\!$&'()*+,;=:%]*))?
@)?
#host-ip
(?<host>(?:[a-zA-Z\d-.%]+)|(?:\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})|(?:\[(?:[a-fA-F\d.:]+)\]))?
#port
(?::(?<port>\d*))?
#slash-path
(?<path>
(?:\/ [a-zA-Z\d\-._~\!$&'()*+,;=:@%]* )*
)
#slash-path
|(?<user>)(?<pass>)(?<host>)(?<port>)
(?<path>\/ [a-zA-Z\d\-._~\!$&'()*+,;=:@%]+(?:\/[a-zA-Z\d\-._~\!$&'()*+,;=:@%]*)*)?
#path
|(?<user>)(?<pass>)(?<host>)(?<port>)
(?<path> [a-zA-Z\d\-._~\!$&'()*+,;=:@%]+(?:\/[a-zA-Z\d\-._~\!$&'()*+,;=:@%]*)*)
)?
#querystring
(?:\?(?<query>[a-zA-Z\d\-._~\!$&'()*+,;=:@%\/?]*))?
#fragment
(?:\#(?<fragment>[a-zA-Z\d\-._~\!$&'()*+,;=:@%\/?]*))?
$
/mg;
// Alternative syntax using RegExp constructor
// const regex = new RegExp('
# allow multiple groups with the same name
(?J)
# protocol user host-ip port path path path querystring fragment
^
#protocol
(?:(?<scheme>[a-zA-Z][a-zA-Z\\d+-.]*):)?
(?|
#slash-slash
\\\/\\\/
#userinfo
(?:
#user
(?<user>[a-zA-Z\\d\\-._~\\!$&\'()*+,;=%]*)
#password
(?::(?<pass>[a-zA-Z\\d\\-._~\\!$&\'()*+,;=:%]*))?
@)?
#host-ip
(?<host>(?:[a-zA-Z\\d-.%]+)|(?:\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})|(?:\\[(?:[a-fA-F\\d.:]+)\\]))?
#port
(?::(?<port>\\d*))?
#slash-path
(?<path>
(?:\\\/ [a-zA-Z\\d\\-._~\\!$&\'()*+,;=:@%]* )*
)
#slash-path
|(?<user>)(?<pass>)(?<host>)(?<port>)
(?<path>\\\/ [a-zA-Z\\d\\-._~\\!$&\'()*+,;=:@%]+(?:\\\/[a-zA-Z\\d\\-._~\\!$&\'()*+,;=:@%]*)*)?
#path
|(?<user>)(?<pass>)(?<host>)(?<port>)
(?<path> [a-zA-Z\\d\\-._~\\!$&\'()*+,;=:@%]+(?:\\\/[a-zA-Z\\d\\-._~\\!$&\'()*+,;=:@%]*)*)
)?
#querystring
(?:\\?(?<query>[a-zA-Z\\d\\-._~\\!$&\'()*+,;=:@%\\\/?]*))?
#fragment
(?:\\#(?<fragment>[a-zA-Z\\d\\-._~\\!$&\'()*+,;=:@%\\\/?]*))?
$
', 'mg')
const str = `https://regex101.com/
https://regex101.com/thing/blah.foo
https://regex101.com:28801/thing/blah/patterns?where_foo=bar&where_primary_access_node=true
https://regex101.com:8443/thing/index.html#/landing`;
// Reset `lastIndex` if this regex is defined globally
// regex.lastIndex = 0;
let m;
while ((m = regex.exec(str)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
// The result can be accessed through the `m`-variable.
m.forEach((match, groupIndex) => {
console.log(`Found match, group ${groupIndex}: ${match}`);
});
}
Please keep in mind that these code samples are automatically generated and are not guaranteed to work. If you find any syntax errors, feel free to submit a bug report. For a full regex reference for JavaScript, please visit: https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions