Regex for an http or https URL
^https?:\/\/[^\s/?#]+(?:[/?#]\S*)?$ with the i flag matches http:// or https://, a host, and an optional path, query or fragment, with no spaces anywhere. For real validation in JavaScript, parse with new URL(s) and check that protocol is http: or https:.
JavaScript ✓PCRE ✓
No catastrophic-backtracking patterns found. (A heuristic check: nested and adjacent repeats, overlapping alternatives.)
^Start of the stringanchorhttpThe text "http" literally (any case, because of the i flag)literalsThe character 's'literal?Repeat it optionally (zero or one time)quantifier:\/\/The text "://" literally (any case, because of the i flag)literal[^\s/?#]Any one character except a whitespace character (space, tab, line break and other Unicode spaces), '/', '?' and '#'character class+Repeat the class one or more times, as many as possible (greedy)quantifier(?:…)Non-capturing group: groups without rememberinggroup[/?#]One character: '/', '?' or '#'character class\SAny character that is not whitespacecharacter type*Repeat it zero or more times, as many as possible (greedy)quantifier?Then repeat the whole group optionally (zero or one time)quantifier$End of the stringanchor
Examples
Checked at build time in JavaScript and in Python's re.
| Input | Matches? |
|---|---|
https://example.com | ✓ match |
http://localhost:8080/path?q=1#top | ✓ match |
HTTPS://EXAMPLE.COM/ | ✓ match |
https://[2001:db8::1]/ | ✓ match |
ftp://example.com | ✗ no match |
https:// | ✗ no match |
https://exa mple.com | ✗ no match |
example.com | ✗ no match |
https://-.- | ✓ match |
https://user:pass@example.com | ✓ match |
Try your own text
One string per line: each line is tested on its own (the m flag is added here).
How it works
The pattern splits a URL where the URL standard does. After the scheme and // comes the authority: everything up to the first /, ? or #. That is [^\s/?#]+. Whatever follows must start with one of those three characters, and the rest is any run of non-space characters.
It does not check that the host is a real domain or IP address. https://-.- passes. Checking hostnames properly means handling IPv6 literals in brackets, ports, user info (user:pass@host), and Unicode domains. A parser already does all of that, so use one when correctness matters and keep the regex for quick filtering, such as finding links in text.
Variants
/https?:\/\/[^\s<>\"']+/giFind URLs inside text. Stops at whitespace, angle brackets and quotes, which usually end a link in HTML or prose./^https:\/\/[^\s/?#]+(?:[/?#]\S*)?$/iRequire HTTPS only, for webhook or callback URLs.
Gotchas
https://-.-andhttp://xboth match. The pattern checks shape, not whether the host could exist.- URLs pasted from prose often end with punctuation. In
see https://example.com/a.the trailing dot is captured by\S*. When extracting links from text, strip trailing.,;:!?)afterward. new URL()accepts schemes likejavascript:anddata:. If you render user-supplied links, checkurl.protocolexplicitly. The regex already restricts the scheme.- Without the
iflag,HTTPS://fails. Schemes are case-insensitive per RFC 3986.
Related explainers
- Regex for an email addressA practical email regex, why a fully RFC 5322-correct one is not worth it, what HTML5's type=email...
- Regex for a URL slugA regex that validates URL slugs like my-first-post: lowercase letters and digits joined by single...
- Regex for an IPv4 addressA strict IPv4 regex that only accepts octets 0-255 and rejects leading zeros, with the edge cases where...