★ Web · regex
Regex for URL
Validates a web URL a user pastes into a form: http or https, a dotted domain with a valid TLD, an optional port, and anything after the first slash, ? or # as long as it has no spaces.
- Runs in your browser
- No signup
Try the url pattern
Read it in plain English (best-effort)
- ^start of a line
- httpthe text 'http'
- sthe character 's'
- ?the previous is optional
- ://the text '://'
- (?:start a group (not captured)
- [A-Za-z0-9]one character from: A–Z, a–z, 0–9
- (?:start a group (not captured)
- [A-Za-z0-9-]one character from: A–Z, a–z, 0–9, '-'
- {0,61}between 0 and 61 of the previous
- [A-Za-z0-9]one character from: A–Z, a–z, 0–9
- )end of group
- ?the previous is optional
- .the character '.'
- )end of group
- +one or more of the previous
- [A-Za-z]one character from: A–Z, a–z
- {2,63}between 2 and 63 of the previous
- (?:start a group (not captured)
- :the character ':'
- \da digit (0–9)
- {1,5}between 1 and 5 of the previous
- )end of group
- ?the previous is optional
- (?:start a group (not captured)
- [\/?#]one character from: '/', '?', '#'
- \Sanything except whitespace
- *zero or more of the previous
- )end of group
- ?the previous is optional
- $end of a line
One sample per line works well with the m flag on anchored patterns.
The pattern, piece by piece
/^https?:\/\/(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\.)+[A-Za-z]{2,63}(?::\d{1,5})?(?:[\/?#]\S*)?$/| Part | What it does |
|---|---|
^https?:\/\/ | http:// or https:// |
(?:label\.)+ | one or more domain labels, each followed by a dot |
[A-Za-z]{2,63} | top-level domain |
(?::\d{1,5})? | optional port, like :8080 |
(?:[\/?#]\S*)? | optional path, query or fragment with no whitespace |
$ | end of the string |
What it accepts and rejects
Every sample below is checked automatically in JavaScript and Python. The tester above is preloaded with all of them, one per line.
| Should match | |
|---|---|
https://example.com | ✓ |
http://example.com/path?q=1#top | ✓ |
https://sub.domain.co.in:8080/a/b | ✓ |
https://my-site.dev/ | ✓ |
https://example.com?ref=tools | ✓ |
https://a.io#section | ✓ |
| Should not match | |
|---|---|
example.com | ✗ |
ftp://example.com | ✗ |
https:// | ✗ |
https://-bad.com | ✗ |
https://example.com/has space | ✗ |
http://localhost:3000 | ✗ |
Copy it into your code
RE2-safeNo lookarounds or backreferences, so the same pattern works in Go's RE2 engine and in Rust's regex crate.
const urlRe = /^https?:\/\/(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\.)+[A-Za-z]{2,63}(?::\d{1,5})?(?:[\/?#]\S*)?$/;
export function isValidUrl(value) {
return urlRe.test(value.trim());
}When not to use regex for this
In code you control, use the platform's URL parser: new URL() in JavaScript, urllib.parse in Python, net/url in Go. It handles IPv6 hosts, encoded characters and edge cases a regex can't. Use the regex for quick form feedback only.
Questions engineers actually ask
Why doesn't it match localhost?
Does it accept URLs without https://?
What is catastrophic backtracking?
More web patterns
- Email AddressPragmatic email check: catches typos without rejecting real addresses.^[A-Za-z0-9_%+-]+(?:\.[A-Za-z0-9_%+-]+)*@[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?(?:\.[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*\.[A-Za-z]{2,}$
- Domain NameHostnames like example.com or sub.example.co.uk, including punycode.^(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\.)+[A-Za-z]{2,63}$
- URL SlugLowercase kebab-case slugs like my-first-post.^[a-z0-9]+(?:-[a-z0-9]+)*$
- IPv4 AddressDotted-quad IPv4 with each octet 0–255 and no leading zeros.^(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$
- IPv6 AddressFull and compressed (::) IPv6 addresses.^(?:(?:[0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}|(?:[0-9A-Fa-f]{1,4}:){1,7}:|(?:[0-9A-Fa-f]{1,4}:){1,6}:[0-9A-Fa-f]{1,4}|(?:[0-9A-Fa-f]{1,4}:){1,5}(?::[0-9A-Fa-f]{1,4}){1,2}|(?:[0-9A-Fa-f]{1,4}:){1,4}(?::[0-9A-Fa-f]{1,4}){1,3}|(?:[0-9A-Fa-f]{1,4}:){1,3}(?::[0-9A-Fa-f]{1,4}){1,4}|(?:[0-9A-Fa-f]{1,4}:){1,2}(?::[0-9A-Fa-f]{1,4}){1,5}|[0-9A-Fa-f]{1,4}:(?::[0-9A-Fa-f]{1,4}){1,6}|:(?:(?::[0-9A-Fa-f]{1,4}){1,7}|:))$
- Hex ColorCSS hex colours: #rgb, #rgba, #rrggbb and #rrggbbaa.^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$
- HTML TagFinds opening, closing and self-closing tags in a string. Not a parser.<\/?([A-Za-z][A-Za-z0-9-]*)\b[^<>]*>
Or browse the full regex library.
More from the workbench
Fine print
Tools: on the house.
Engineer: by the hour.
The regex was free. Code that doesn't need one is the upgrade: typed schemas, validated once at the edge, trusted everywhere after.
I'm Himanshu, an AI and full-stack engineer. I build MVPs, AI agents and the growth plumbing around them for early-stage startups.
