Examples
September 13, 2026 · View on GitHub
Overview
The example below demonstrates highlighting URLs in text, combining cases of varying complexity.
Input:
A URL with a scheme is the easy case: http://example.com, and https://example.com works the same.
Other schemes are matched as well, for example ftp://example.com.
Without a scheme it still works, example.com becomes a link, but readme.txt does not.
Punctuation belongs to the sentence, not to the URL: did you visit http://example.com?
A comma stays out of example.com/first, a semicolon out of example.com/second; and a trailing dot out of example.com/third.
Brackets are matched in pairs, so an enclosed URL stays whole (http://example.com/path/(brackets)), and a quoted one too: "example.com/path".
Emails become mailto links, write to user@example.com, to user+tag@mail.example.com, or spell the scheme out as mailto:user@example.com.
A host may carry a port, example.com:8080/path, or be an IP address, 127.0.0.1:8080/health, while a version number such as 1.2.3.4 stays plain text.
Credentials are kept, http://user:pass@example.com, and so is Unicode, http://приклад.укр/привіт.
A path may have several segments, and a query several parameters: example.com/store/catalog/laptops?size=14"&color=black#results.
Long and complex URLs are highlighted correctly, query and fragment included: http://elk.example.com:81/app/kibana#/discover?_g=()&_a=(columns:!(_source),index:'deve-',interval:auto,query:(query_string:(analyze_wildcard:!t,query:'')),sort:!('@timestamp',desc)).
An existing link, like <a href="http://example.com">example.com</a>, is not highlighted twice.
Result:
A URL with a scheme is the easy case: http://example.com, and https://example.com works the same.
Other schemes are matched as well, for example ftp://example.com.
Without a scheme it still works, example.com becomes a link, but readme.txt does not.
Punctuation belongs to the sentence, not to the URL: did you visit http://example.com?
A comma stays out of example.com/first, a semicolon out of example.com/second; and a trailing dot out of example.com/third.
Brackets are matched in pairs, so an enclosed URL stays whole (http://example.com/path/(brackets)), and a quoted one too: "example.com/path".
Emails become mailto links, write to user@example.com, to user+tag@mail.example.com, or spell the scheme out as mailto:user@example.com.
A host may carry a port, example.com:8080/path, or be an IP address, 127.0.0.1:8080/health, while a version number such as 1.2.3.4 stays plain text.
Credentials are kept, http://user:pass@example.com, and so is Unicode, http://приклад.укр/привіт.
A path may have several segments, and a query several parameters: example.com/store/catalog/laptops?size=14"&color=black#results.
Long and complex URLs are highlighted correctly, query and fragment included: http://elk.example.com:81/app/kibana#/discover?_g=()&_a=(columns:!(_source),index:'deve-',interval:auto,query:(query_string:(analyze_wildcard:!t,query:'')),sort:!('@timestamp',desc)).
An existing link, like example.com, is not highlighted twice.
Note
GitHub does not allow the ftp scheme when it renders Markdown, so the FTP example above shows as plain text on this page.
The library does produce the anchor, visible in the Markdown source of this page.
Matching
The table shows which part of the input is matched as a URL, and the rule that applies.
| Input | Matched URL | Rule |
|---|---|---|
Visit http://example.com today. | http://example.com | URL with a (any) scheme is always matched |
Visit example.com today. | example.com | no scheme, host has a known top-level domain |
Read readme.txt now. | not matched | txt is not a top-level domain |
Did you visit http://example.com? | http://example.com | trailing punctuation belongs to the text |
See (example.com/path/(brackets)) here. | example.com/path/(brackets) | brackets are matched in pairs |
Quote "example.com/path" here. | example.com/path | enclosing quotes belong to the text |
Contact user@example.com now. | user@example.com | |
Contact mailto:user@example.com now. | mailto:user@example.com | email with the scheme |
Visit example.com:8080/path now. | example.com:8080/path | host with a port |
Check 127.0.0.1:8080/health now. | 127.0.0.1:8080/health | IP host with a port or a path |
Version 1.2.3.4 released. | not matched | IP host without a port or a path |
Login http://user:pass@example.com now. | http://user:pass@example.com | credentials are part of the URL |
Visit http://приклад.укр/привіт now. | http://приклад.укр/привіт | Unicode host and path |
Tip
For the full set of cases, see UrlRegexTest, MatcherTest and UrlHighlightTest.
Formats
The format tells the library how to read the input. With the HTML formats, tags stay as they are and URLs are matched only in the text between them.
| Format | Input | Output |
|---|---|---|
Format::Html | <p>Visit example.com now.</p> | <p>Visit <a href="http://example.com">example.com</a> now.</p>URL highlighted, anchor may be placed inside p |
Format::Html | <a href="http://example.com">example.com</a> | <a href="http://example.com">example.com</a>not changed, the URL is already a link |
Format::Html | <script>var u = "example.com";</script> | <script>var u = "example.com";</script>not changed, elements that may not contain an anchor are skipped: a, button, datalist, math, script, select, style, svg, textarea, title |
Format::HtmlEncoded | <b>example.com?a=1&b=2</b> | <b><a href="http://example.com?a=1&b=2">example.com?a=1&b=2</a></b>URL matched against the decoded text, the original encoding is kept |
Format::Html | <b>example.com?a=1&b=2</b> | <b><a href="http://example.com?a=1&amp;b=2&lt;/b&gt">example.com?a=1&amp;b=2&lt;/b&gt</a>;wrong format for this input, the match runs past the URL, into the markup that follows |
Format::Plain | Mail <user@example.com> please. | Mail <<a href="mailto:user@example.com">user@example.com</a>> please.angle brackets are ordinary characters, Format::Html would read <user@example.com> as a tag |