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=()&amp;_a=(columns:!(_source),index:&apos;deve-&apos;,interval:auto,query:(query_string:(analyze_wildcard:!t,query:&apos;&apos;)),sort:!(&apos;@timestamp&apos;,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.

InputMatched URLRule
Visit http://example.com today.http://example.comURL with a (any) scheme is always matched
Visit example.com today.example.comno scheme, host has a known top-level domain
Read readme.txt now.not matchedtxt is not a top-level domain
Did you visit http://example.com?http://example.comtrailing 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/pathenclosing quotes belong to the text
Contact user@example.com now.user@example.comemail
Contact mailto:user@example.com now.mailto:user@example.comemail with the scheme
Visit example.com:8080/path now.example.com:8080/pathhost with a port
Check 127.0.0.1:8080/health now.127.0.0.1:8080/healthIP host with a port or a path
Version 1.2.3.4 released.not matchedIP host without a port or a path
Login http://user:pass@example.com now.http://user:pass@example.comcredentials 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.

FormatInputOutput
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&lt;b&gt;example.com?a=1&amp;b=2&lt;/b&gt;&lt;b&gt;<a href="http://example.com?a=1&amp;b=2">example.com?a=1&amp;b=2</a>&lt;/b&gt;
URL matched against the decoded text, the original encoding is kept
Format::Html&lt;b&gt;example.com?a=1&amp;b=2&lt;/b&gt;&lt;b&gt;<a href="http://example.com?a=1&amp;amp;b=2&amp;lt;/b&amp;gt">example.com?a=1&amp;amp;b=2&amp;lt;/b&amp;gt</a>;
wrong format for this input, the match runs past the URL, into the markup that follows
Format::PlainMail <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