Free · Fast · Privacy-first

Regex for URL Validation, Test Patterns Against Real URLs

URL validation regex needs to handle schemes, subdomains, paths, query strings, fragments, and encoded characters while still rejecting plainly malformed strings.

Test URL patterns against edge cases: IPs, ports, query strings, fragments

🔒

Verify scheme handling for http, https, and custom protocols

Check that subdomains and multi-label TLDs are accepted

Confirm malformed URLs are correctly rejected

Cost
Free forever
Sign-up
Not required
Processing
In your browser
Privacy
Files stay local
FreeNo signupWhite-label

Add this Regex Tester to your website

Drop the Regex Tester into any page — blog post, product docs, intranet, school portal — with a single line of HTML. Your visitors get the full tool, processed entirely in their browser. No backend, no uploads, no signup.

  • Files stay 100% in the visitor's browser
  • Responsive — adapts to any container width
  • Free forever, no API key needed

Embed code

<iframe
  src="https://www.fixtools.io/developer/regex-tester?embed=1"
  width="100%"
  height="780"
  frameborder="0"
  style="border:0;border-radius:16px;max-width:900px;"
  title="Regex Tester by FixTools"
  loading="lazy"
  allow="clipboard-write"
></iframe>

Attribution-friendly: a small "Powered by FixTools" link appears in the embed footer.

URL Validation Regex: Anatomy, Tradeoffs, and Practical Patterns

A URL has up to eight components: scheme, authority (userinfo, host, port), path, query, and fragment. A regex that validates all components in full detail becomes unwieldy: the RFC 3986 grammar for a generic URI spans over a page of production rules. For web application validation, a practical URL regex focuses on the most common form: an optional scheme (http:// or https://), a hostname consisting of labels separated by dots, an optional port, an optional path, optional query string, and optional fragment. Edge cases that a practical pattern can intentionally omit include IP address literals in bracket notation, IPv6 addresses, percent-encoded characters in the host, userinfo credentials embedded in the URL, and data URIs that embed file content directly. Excluding these keeps the pattern readable and maintainable without meaningfully reducing its usefulness for the vast majority of real-world URLs.

A widely-used practical URL pattern is: ^(https?:\/\/)([\da-z\-.]+)\.([a-z.]{2,6})([\w\-._~:/?#\[\]@!$&'()*+,;=%]*)$. Breaking this down: https?:\/\/ matches http:// or https://; [\da-z\-.]+ matches subdomain and domain labels; the TLD group covers two to six character labels (though extending to {2,} is advisable given long modern TLDs); and the final character class covers all RFC 3986 path, query, and fragment characters. In JavaScript string notation the double backslash is required; when entering directly into a regex tester, single backslashes are the correct form. Always test both the expanded and the compact forms to confirm they match identically.

For scraping and content extraction use cases, the validation question shifts from "is this a valid URL per spec?" to "is this a link worth following?" Extraction patterns are looser and anchor-free, designed to find URL-like substrings within larger blocks of text. Validation patterns are stricter and anchor the entire string with ^ and $. Decide which use case you have before writing the pattern: the two goals produce very different regex designs with different tradeoffs around false positives and false negatives. Mixing the two approaches without awareness of this distinction is the most common source of URL pattern bugs in production code.

URL regex is also a notorious source of catastrophic backtracking. Patterns that allow multiple optional segments combined with broad character classes can explode on malicious inputs designed to maximise the engine's exploration of impossible match paths. The classic dangerous shape is something like ^(https?://)?([a-zA-Z0-9]+\.)+[a-zA-Z0-9]+(/.*)?$ applied to a 200-character input ending with a single disallowed character: the engine explores every possible way to partition the dot-separated host before declaring no match. The fix is to unroll the loop into ^https?://[a-zA-Z0-9]+(\.[a-zA-Z0-9]+)*(/.*)?$ which has no ambiguous overlap between segments. Before deploying any URL regex on a route that accepts user input, run it through a static analyser like safe-regex2 or test it against deliberately pathological strings to confirm worst-case behaviour stays linear.

How to use this tool

💡

Paste your URL validation pattern and a list of URLs (one per line) including edge cases: URLs with query strings, fragments, subdomains, ports, and intentionally malformed strings.

How It Works

Step-by-step guide to regex for url validation, test patterns against real urls:

  1. 1

    Open the Regex Tester

    Navigate to the FixTools Regex Tester using the link on this page. The browser-based tool requires no setup and activates immediately, so you can begin testing your URL pattern within seconds of arriving on the page.

  2. 2

    Enter your URL pattern

    Paste your URL validation regex into the pattern field. A practical starting point that handles the most common cases is ^https?:\/\/[\w\-]+(\.[\w\-]+)+[\w\-._~:/?#\[\]@!$&'()*+,;=%]*$. This accepts both HTTP and HTTPS URLs with standard hostnames, paths, query strings, and fragments. Adjust the scheme prefix and character classes to match your specific acceptance criteria.

  3. 3

    Enable g and m flags

    Use the global and multiline flags to evaluate a full list of URLs in a single test run. Each URL on a separate line is checked independently, giving you a clear visual result for every sample without having to paste and test each URL one by one.

  4. 4

    Paste sample URLs

    Include a diverse test set: valid URLs with subdomains, paths, query strings, fragments, and port numbers; valid URLs with long TLDs; and deliberately malformed strings such as "not-a-url", "ftp://legacy.example.com", "javascript:alert(1)", and a bare domain without a scheme. Confirming correct rejection of malformed and potentially dangerous inputs is as important as confirming acceptance of valid ones.

Real-world examples

Common situations where this approach makes a real difference:

Validating a URL input field in a link-sharing application

A link-sharing app needs to accept https://www.example.com/path?q=1#section while rejecting "javascript:alert(1)", "file:///etc/passwd", and plain text strings entered in the URL field. The pattern ^https?:\/\/[\w\-.]+\.[a-z]{2,}([\w\-._~:/?#\[\]@!$&'()*+,;=%]*)$ accepts the valid URL and rejects all three problematic inputs. The developer tests ftp:// to confirm it is also rejected, and tests a URL with a query string containing an ampersand to confirm the query character class includes it.

Extracting all URLs from a block of scraped HTML text

A web scraper processes raw HTML as plain text and needs to pull all href attribute values from anchor tags. The anchor-free pattern https?:\/\/[\w\-]+(\.[\w\-]+)+[\w\-._~:/?#\[\]@!$&()*+,;=%]* with the g flag finds every HTTP and HTTPS URL in a pasted block of raw HTML. Testing against a sample page's source in the tester confirms the pattern captures full URLs including those with long query strings and hash fragments without stopping prematurely at an unexpected character.

Blocking URLs from a comment field to prevent spam

A comment moderation system needs to flag user submissions containing URLs for human review before publishing. The detection pattern https?:\/\/\S+ is intentionally permissive: it identifies any HTTP or HTTPS URL-like substring in the comment text rather than strictly validating URL structure. Testing against a sample set of known spam comments in the tester confirms all URL-containing submissions are flagged, and testing against comments mentioning "https" in a non-URL context (such as in a sentence) reveals whether the pattern needs a word boundary or space constraint.

Validating webhook URLs in an API integration setup

An API platform validates webhook endpoint URLs before saving them to ensure only reachable HTTPS endpoints are registered. The pattern ^https:\/\/[\w\-]+(\.[\w\-]+)+(:\d{1,5})?(\/.*)? restricts to HTTPS only, supports an optional port number, and accepts any path after the host. Testing confirms https://api.service.com/webhook/v2 and https://internal.company.net:8443/hooks are accepted, while http:// URLs, bare domains without a scheme, and URLs with disallowed characters are all rejected.

When to use this guide

Use this page when you need to validate or extract URLs in a form field, web scraper, content moderation system, or data pipeline and want to test your pattern against real URL samples.

Pro tips

Get better results with these expert suggestions:

1

Use the URL API for validation in modern JavaScript environments

In browser and Node.js contexts, new URL(string) throws a TypeError for malformed URLs and succeeds silently for valid ones, covering all RFC 3986 edge cases including IPv6, IDN hostnames, and percent-encoding without any regex complexity. Use regex for extraction tasks where you need to find URLs inside larger text, and use the URL API for validation tasks where you have a candidate string and need to confirm it is a well-formed URL. Combining both tools gives you fast extraction followed by authoritative validation.

2

Decide whether to allow non-HTTPS schemes before writing the pattern

For user-submitted link fields, restricting to https:// only by anchoring the scheme as ^https:\/\/ is a security best practice that blocks javascript:, data:, and file: scheme injection attempts. For internal developer tools that process URLs from controlled sources, allowing http:// may be necessary for testing against local servers. Make this decision before writing the pattern and encode it explicitly rather than treating scheme restriction as an afterthought you can add later.

3

Test URLs with all components: path, query, fragment, and port

Most URL validation bugs appear at the boundaries between components. A pattern that correctly accepts https://example.com may reject https://example.com:8080/path?foo=bar#section because the port or query character class is too restrictive. Build a test set that includes at least one URL exercising each component individually and one URL with all components combined. Run the full set in the tester before marking the pattern ready for use.

4

Use a character class for path characters rather than .*

Using the RFC 3986 allowed character set [\w\-._~:/?#\[\]@!$&'()*+,;=%]* instead of .* for the path, query, and fragment portion prevents the pattern from greedily consuming content beyond the end of a URL when matching inside a larger block of text. This matters for extraction patterns where .* can span across multiple URLs on the same line, merging two separate links into a single false match.

FAQ

Frequently asked questions

A commonly used starting pattern is ^https?:\/\/([\da-z\-.]+)\.([a-z.]{2,6})([\w\-._~:/?#\[\]@!$&'()*+,;=%]*)$. This accepts HTTP and HTTPS URLs with standard hostnames, paths, query strings, and fragments. It does not handle IPv6 addresses, data URIs, internationalized domain names, or non-ASCII paths. For production JavaScript, supplement it with the URL constructor (new URL()) for stricter validation after the regex confirms the basic shape.
Replace the https? scheme group with the literal https, making the S mandatory: ^https:\/\/. This rejects all HTTP URLs, javascript: scheme URIs, file: paths, ftp: URLs, and any other scheme. HTTPS-only validation is recommended for any field that accepts user-submitted links, as it prevents scheme injection attempts and ensures the link target uses an encrypted connection. Test both https:// and http:// inputs in the tester to confirm only HTTPS passes.
Use an anchor-free version of your pattern with the g flag enabled. Remove the ^ and $ anchors so the engine searches for URL-shaped substrings rather than requiring the full string to be a URL. The pattern https?:\/\/[\w\-]+(\.[\w\-]+)+[\w\-._~/?#=&%+.]* with the g flag extracts all HTTP and HTTPS URLs from a block of text in a single pass. Test against a paragraph that contains multiple URLs and prose to confirm the pattern stops at the right position for each URL.
The query string starts after ? and may contain characters like =, &, %, and + that are not covered by basic word character classes (\w). Ensure your path and query character class explicitly includes these common query string characters: [\w\-._~:/?#\[\]@!$&()*+,;=%]. Alternatively, use [^\s]* to match any non-whitespace character sequence after the host, which is a permissive but reliable approach for extracting full URLs from text.
Use the URL API (new URL(string)) for validation in any environment that supports it, which includes all modern browsers and Node.js 10 and later. It handles all RFC 3986 edge cases without any regex complexity. Use regex when you need to extract URLs from freeform text, restrict to specific schemes, or validate in environments where the URL API is unavailable. For most modern web applications, the URL API is the more reliable validation mechanism.
Add an optional port group immediately after the hostname: (:\d{1,5})? matches a colon followed by one to five digits, covering port 1 through 99999. The valid TCP/UDP port range is 1 to 65535. If you need to enforce strict port range validity, you cannot express this cleanly with a character count alone, so capture the port with the regex and then validate the numeric value separately in your code after extraction. Remember that ports 0 and 65536-99999 fall outside the assigned range, so a post-parse numeric check is the simplest way to reject them without bloating the pattern. If your tool only ever expects standard web traffic, restrict the optional group to (:(80|443|8080|8443))? and reject everything else at the regex layer.
Anchor the scheme explicitly to http or https by starting the pattern with ^https?:. This ensures only those two schemes can match. If you have a longer list of schemes to block and cannot restrict the allowed schemes directly, use a negative lookahead at the start: ^(?!javascript:)(?!data:)(?!file:)\S+ enumerates the blocked schemes. Test against javascript:alert(1), data:text/html;base64,... and file:///etc/passwd in the tester to verify all three are rejected.
Standard ASCII-based URL patterns do not match IDN (internationalized domain name) URLs directly because the domain is encoded as punycode (e.g. xn--nxasmq6b.com). If your application receives punycode-encoded IDN URLs, the standard pattern handles them fine since punycode uses only ASCII characters. For matching Unicode domain names as typed (e.g. example.com in Cyrillic), use the URL API to parse and normalise the URL first, then validate the normalised form.
Regex is fine for the question "is this string roughly URL-shaped?" but quickly becomes wrong for any question that requires understanding URL semantics: extracting query parameters by name, resolving relative URLs against a base, comparing two URLs for equivalence after normalisation, or handling percent-encoded characters in the path correctly. For every one of these, the URL constructor in JavaScript (new URL(input)) or urllib.parse.urlparse in Python does the work correctly in one line. Use regex when you need to find URL-shaped substrings inside larger text and when an approximate match is sufficient. Switch to a parser whenever the next step involves inspecting or transforming any part of the URL's structure beyond confirming that it exists.
A URL that passes a simple regex check can still be dangerous. Open-redirect attacks use whitelisted hosts with a misleading path: a redirect to evil.com/login?next=https://your-site.com.evil.com passes a naive contains check. Server-side request forgery uses URLs pointing at internal IPs like http://169.254.169.254/ (the AWS metadata endpoint) or http://localhost:6379/. Scheme injection uses javascript: or data: prefixes that look URL-like and execute when rendered as a link. Always combine your regex check with explicit allowlist validation for the scheme (https only), explicit blocklist checks against link-local and private IP ranges if the URL will be fetched server-side, and HTML escaping when reflecting the URL back into a page.

Related guides

More use-case guides for the same tool:

Ready to get started?

Open the full Regex Tester — free, no account needed, works on any device.

Open Regex Tester →

Free · No account needed · Works on any device