PatternRegex

Match a web URL

Find http and https links in free text — commit messages, chat logs, scraped pages — without dragging in half the punctuation around them.

Last updated

Patterng
https?:\/\/[\w.-]+(?:\/[\w./?%&=-]*)?
Open in Regex Tester & Builder

Matches

  • https://docs.example.com/v2/setup
  • http://example.com
  • https://a-b.co/x?y=1

Doesn’t match

  • ftp://files.example.com
  • example.com
  • mailto:me@example.com

Why it’s written this way

https? makes the s optional so one pattern covers both schemes. The host is [\w.-]+ — letters, digits, dots and hyphens — and the whole path group is optional, so a bare domain link still matches.

The path's character class is deliberately narrow. URL-matching patterns mostly fail by being greedy: allow every legal URL character and the match swallows the closing bracket, comma or full stop that follows the link in prose.

Edge cases to know

  • →Query strings using characters outside [\w./?%&=-] (like + or #fragments) are cut short at that character.
  • →It does not validate the domain has a real TLD — ftp://, mailto: and bare hosts are out of scope by design.
  • →For parsing a URL you already have (rather than finding them in text), use a URL parser, not a regex.

Part by part

https?
Matches http with an optional s. The question mark applies to the single preceding character, which is the whole trick here.
:\/\/
The scheme separator. The slashes are escaped because this pattern is written to survive being pasted into a /.../ literal in JavaScript.
[\w.-]+
The host: word characters, dots and hyphens. Covers subdomains and hyphenated names, and stops at the first character a hostname cannot contain.
(?:\/[\w./?%&=-]*)?
The optional path and query. The whole group is optional, so a bare origin matches; inside it, the class covers the punctuation that survives in a real query string.

Common mistakes

  • https?://.*

    The trailing .* is greedy and matches to the end of the line, so a URL mentioned mid-sentence swallows the rest of the sentence with it — including any second URL on the same line.

    https?:\/\/[\w.-]+(?:\/[\w./?%&=-]*)?
  • www\.[\w.-]+

    Keying on the www prefix misses most modern URLs, which do not use it, while matching the bare text "www.example.com" that was never a link. The scheme is the reliable signal.

  • https?:\/\/\S+

    Matching every non-space character grabs the closing bracket or quotation mark that follows a URL in prose or markup, producing a link that 404s in a way that is annoying to debug.

Questions

Does it match a URL written without a scheme, like example.com?

No, and that is deliberate: requiring http or https is what separates a link from an ordinary sentence containing a dot. If you need bare domains too, add an alternative rather than loosening this branch.

Why does it sometimes include the full stop at the end of a sentence?

Because a dot is a legitimate character inside a path, the pattern cannot tell a trailing sentence-ending dot from part of the URL. Trimming trailing punctuation after matching is more reliable than trying to encode the distinction in the pattern.

Does it handle internationalised domains?

Only in their punycode form, such as xn--80ak6aa92e.com, because the host class is limited to word characters. Unicode domains written natively will not match — normalise to punycode first if you need to catch them.

Is this safe for deciding whether to follow a link?

No. It is a finder, not a validator, and it says nothing about where a URL leads. Anything security-sensitive should parse the match with a real URL parser and check the resulting host against an allowlist.

Related in Patterns