/^/
MediumWeb5 min read

URL Regex

Validates HTTP and HTTPS URLs with a required host containing at least one dot, an optional port, and an optional path, query, or fragment.

#url#web#http#validation#links#parsing

Regex Pattern

^https?:\/\/[\w-]+(\.[\w-]+)+(:\d+)?([\/?#][^\s]*)?$

Pattern Breakdown

Hover over a token to see what it does.

^https?:\/\/[\w-]+(\.[\w-]+)+(:\d+)?([\/?#][^\s]*)?$
TokenMeaning
^Anchors the match to the start of the string
https?Matches http or https (the trailing s is optional)
:\/\/Literal :// scheme separator
[\w-]+(\.[\w-]+)+Hostname made of one or more dot-separated labels, requiring at least one dot
(:\d+)?Optional port number, e.g. :8080
([\/?#][^\s]*)?Optional path, query string, or fragment starting with /, ?, or #
$Anchors the match to the end of the string

Detailed Explanation

What it does

This pattern validates that a string is a well-formed absolute HTTP or HTTPS URL: a scheme, a dotted hostname, an optional port, and an optional path/query/fragment. It rejects strings without a recognized scheme or without any dot in the host.

Why it works

The scheme is matched literally with an optional trailing s for https. The hostname requires at least two dot-separated labels, which filters out bare words like 'localhost' that lack a domain suffix. The optional groups for port and path let the pattern accept both bare domains and fully-specified URLs while still anchoring the whole string so trailing garbage or embedded spaces are rejected.

Common use cases

  • Validating a website field in a signup or profile form
  • Filtering user-submitted text for strings that look like clickable links
  • Sanity-checking configuration values that must be absolute HTTP(S) URLs
  • Basic pre-flight validation before passing a string to a URL constructor

Edge cases

  • URLs with a port like https://example.com:8080/path are matched
  • Bare hostnames without a dot such as http://localhost are intentionally rejected
  • Query strings and fragments combined, like ?q=1#section, are accepted by the trailing group
  • IP-address hosts such as http://192.168.1.1 are rejected because they don't match the [\w-]+ label pattern with letters expected
  • Internationalized domain names with non-ASCII characters will not match without punycode conversion

Limitations

  • Does not validate URL scheme beyond http/https (no ftp, mailto, ws, etc.)
  • Does not fully validate percent-encoding correctness in the path or query
  • Cannot confirm the host is reachable or resolves via DNS
  • Does not support IPv4 or IPv6 literal hosts without modification

Interactive Tester

Edit the pattern or text below — matching runs live in your browser.

https://example.com http://example.com/path?query=1 https://sub.example.co.uk/path#frag

Test Cases

Editable — add your own inputs to see if they pass.

InputExpectedResult
Pass
Pass
Pass
Pass
Pass
Pass
Pass
Pass
Pass

Language Variants

Production-ready examples in 12 languages.

const urlRegex = /^https?:\/\/[\w-]+(\.[\w-]+)+(:\d+)?([\/?#][^\s]*)?$/;
console.log(urlRegex.test('https://example.com/path')); // true

Common Mistakes

Forgetting the scheme is required, so 'example.com' is rejected even though browsers accept it

Fix: Either require the scheme explicitly in the UI or prepend https:// before validating if a bare domain should be accepted

Using this regex to also validate deep-linked scheme URLs like mailto: or tel:

Fix: Write a separate pattern or scheme whitelist for non-HTTP schemes rather than extending this one

Escaping the / characters unnecessarily in JavaScript regex literals, causing confusion when porting to other languages

Fix: In JS regex literals, / must be escaped as \/, but in most other languages' string-based patterns it does not need escaping

Performance Notes

  • The hostname group (\.[\w-]+)+ is a repeated group and can be slightly slower on pathological long strings, but real-world hostnames are short so this is not a practical risk
  • Anchoring with ^ and $ avoids scanning for a match anywhere in a long string
  • The trailing [^\s]* is greedy but has no ambiguity with the surrounding pattern, so no catastrophic backtracking occurs

Browser Compatibility

EngineSupportedNotes
ChromeYes
FirefoxYes
SafariYes
EdgeYes
Node.jsYes