How to Validate a URL with Regex: HTTP, HTTPS, Domains, and Query Strings
Short answer: use a whole-string pattern when you need a quick URL shape check, but use the native URL parser when your application must reliably separate protocol, hostname, port, path, query, and fragment. RegexToolBox can generate, test, and compare the pattern across several language examples; it cannot replace URL parsing, DNS checks, or an HTTP request.
What this URL regex validates
The practical pattern below accepts HTTP and HTTPS URLs with a DNS-style domain, an optional port, an optional path, an optional query string, and an optional fragment:
^https?:\\/\\/(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\\.)+[A-Za-z]{2,}(?::\\d{1,5})?(?:\\/[^\\s?#]*)?(?:\\?[^\\s#]*)?(?:#[^\\s]*)?$ This is a practical web-form filter. It deliberately targets hostnames such as example.com and does not attempt to implement every URI rule, internationalized domain form, IPv6 literal, user-info credential, or local development hostname.
Break the pattern into URL parts
^and$require the complete input to match, so a valid URL cannot be hidden inside extra text.https?allowshttporhttps.\\/\\/requires the authority separator after the scheme.(?:...\\.)+[A-Za-z]{2,}requires one or more DNS labels and a two-character-or-longer alphabetic top-level label. Each label starts and ends with an alphanumeric character, while internal hyphens are allowed.(?::\\d{1,5})?allows an optional numeric port such as:8080.(?:\\/[^\\s?#]*)?allows a path and stops it from consuming the query or fragment markers.(?:\\?[^\\s#]*)?allows a query string, including parameters separated by&.(?:#[^\\s]*)?allows a fragment after the query or path.
HTTP and HTTPS only
If the input policy allows only secure URLs, change the scheme part to https:
^https:\\/\\/(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\\.)+[A-Za-z]{2,}(?::\\d{1,5})?(?:\\/[^\\s?#]*)?(?:\\?[^\\s#]*)?(?:#[^\\s]*)?$ Keep the http alternative when a site accepts both schemes. A regex match says only that the text has the expected shape; it does not prove that the server supports the scheme or that a certificate is valid.
Domains, ports, paths, and query strings
Domain names
The domain branch rejects empty labels, leading or trailing hyphens, and a missing dot. It accepts subdomains such as docs.example.com. This policy excludes localhost, bare internal names, and IP addresses. Add separate alternatives if your product explicitly supports those inputs.
Ports
The optional port branch accepts one to five digits. It does not know whether a port is registered, reachable, or appropriate for HTTP. If you need the numeric range from 1 through 65535, parse the captured port and apply a numeric check in application code.
Paths
The path branch accepts ordinary URL characters until whitespace, ?, or #. It therefore handles values such as /products/regex-guide and encoded segments such as /search/%5Burl%5D without trying to decode them inside the regex.
Query parameters and fragments
The query branch accepts one or more non-space characters after ?, including multiple parameters such as ?q=regex&page=2. The fragment branch handles values after #. Regex does not verify that a parameter name is unique, that a value is URL-encoded, or that a server recognizes the parameter.
Regex or the native URL parser?
Use regex at the input boundary when you need a lightweight shape check, a search filter, or a quick test fixture. Use the native parser for routing, security decisions, canonicalization, redirects, allowlists, and any workflow that needs trustworthy components.
In JavaScript, new URL(value) parses an absolute URL and exposes protocol, hostname, port, pathname, search, and hash. The parser also normalizes some representations and throws for malformed input. In other languages, use the standard URL or URI parser available in that runtime. Treat parser success as syntax validation, then apply your own policy for allowed schemes, hosts, ports, and credentials.
Test the pattern in RegexToolBox
- Open the RegexToolBox regex tester.
- Paste the pattern into the Generated Regex field, or describe the requirement and choose Generate Regex with AI.
- Select JavaScript, PHP, Python, Java, or C# to see a language-specific code example.
- Put one URL per line in Test Content (one per line).
- Click Validate and review the per-line Validation Results.
Valid and invalid examples
| Input | Expected | Reason |
|---|---|---|
https://example.com | Valid | HTTPS scheme and DNS-style domain |
http://docs.example.com:8080/guide | Valid | HTTP, subdomain, port, and path |
https://example.com/search?q=regex&page=2#results | Valid | Query parameters and fragment |
https://sub.example.co.uk/a%20b | Valid | Multi-label domain and encoded path segment |
ftp://example.com/file | Invalid | Scheme is outside the HTTP/HTTPS policy |
https://localhost:3000 | Invalid | Local hostnames are excluded by this domain policy |
https://-example.com | Invalid | Domain label starts with a hyphen |
https://example.com/path with spaces | Invalid | Whitespace is not allowed |
example.com | Invalid | Scheme and authority separator are missing |
https://192.0.2.10 | Invalid | IPv4 literals are outside this hostname-only pattern |
Language escaping examples
The regex engine receives the same logical pattern, but the host language may require an extra level of escaping. These snippets show the practical pattern in common forms.
JavaScript
const urlPattern = /^https?:\\/\\/(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\\.)+[A-Za-z]{2,}(?::\\d{1,5})?(?:\\/[^\\s?#]*)?(?:\\?[^\\s#]*)?(?:#[^\\s]*)?$/;
const isValidShape = urlPattern.test(value); PHP
$pattern = '~^https?://(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\\.)+[A-Za-z]{2,}(?::\\d{1,5})?(?:/[^\\s?#]*)?(?:\\?[^\\s#]*)?(?:#[^\\s]*)?$~';
$isValidShape = preg_match($pattern, $value) === 1; Python
import re
url_pattern = re.compile(r'^https?://(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\\.)+[A-Za-z]{2,}(?::\\d{1,5})?(?:/[^\\s?#]*)?(?:\\?[^\\s#]*)?(?:#[^\\s]*)?$')
is_valid_shape = url_pattern.fullmatch(value) is not None Java
String regex = "^https?://(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\\\\.)+[A-Za-z]{2,}(?::\\\\d{1,5})?(?:/[^\\\\s?#]*)?(?:\\\\?[^\\\\s#]*)?(?:#[^\\\\s]*)?$";
boolean isValidShape = Pattern.compile(regex).matcher(value).matches(); C#
var pattern = @"^https?://(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\\.)+[A-Za-z]{2,}(?::\\d{1,5})?(?:/[^\\s?#]*)?(?:\\?[^\\s#]*)?(?:#[^\\s]*)?$";
bool isValidShape = Regex.IsMatch(value, pattern); When a language uses a normal quoted string, each regex backslash may need another backslash for the string literal. Raw strings, verbatim strings, regex literals, and delimiter choices can reduce that extra escaping. Always test the final runtime string, not only the source-code appearance.
Common questions
What is the best regex for URL validation?
There is no universal best pattern. Choose a policy for schemes, hostnames, ports, paths, queries, and fragments, then keep the expression as narrow as your input requires.
Can this regex validate every legal URL?
No. It is a hostname-focused HTTP/HTTPS filter. It excludes IPv4 and IPv6 literals, localhost, user-info credentials, internationalized domains, and less common URI schemes.
Does a match prove the URL works?
No. A match checks text shape only. It does not perform DNS resolution, certificate validation, connectivity checks, or an HTTP request.
When should I use new URL instead?
Use the native parser when you need reliable URL components, canonicalization, allowlist checks, redirects, or security-sensitive decisions. Apply your product policy after parsing.
How do I test language escaping?
Paste the logical pattern into RegexToolBox, choose the target language, copy the generated example, and run it against the same one-per-line test set. Confirm that the runtime receives the intended backslashes.