How to Extract All URLs from Any Text (Online Tool, Regex & Python)

Updated July 25, 2026

🛠️ This guide pairs with our free URL Extractor from Text — Instantly pull every link, email or domain out of any text — huge inputs, zero limits.

You have a wall of text — an email thread, a server log, an exported chat, a saved page’s HTML — and you need the links out of it. All of them, deduplicated, as a clean list. This is one of those tasks that’s either ten seconds or an hour depending on the method, so here are the three that work, plus the regex details that trip everyone up.

Method 1: instant, in your browser

Paste the text into our free URL Extractor and the links appear as you paste — no button to click, no size limit, no daily quota. Toggles handle the variations that matter in real text:

Everything runs client-side in your browser: the text never uploads anywhere, which matters when the source is private email or production logs. Export as TXT, CSV or JSON when you’re done.

Method 2: regex (and why URL regex is harder than it looks)

The naive pattern everyone writes first is http\S+ — and it immediately over-captures. Real text wraps URLs in punctuation: (see https://example.com/page). captures the trailing ). and now your list is full of broken links.

A pattern that behaves well in practice:

https?://[^\s<>"'\]\[{}|\\^]+

…followed by a cleanup pass that strips trailing punctuation (.,;:!?)) — but only strips a closing ) when the URL doesn’t contain a matching (, because Wikipedia URLs like /wiki/Python_(programming_language) legitimately end in one. That asymmetric-paren rule is the detail virtually every regex snippet on Stack Overflow gets wrong.

Other real-world gotchas:

Method 3: Python

For pipelines, combine the regex with cleanup and dedup:

import re

URL_RE = re.compile(r'https?://[^\s<>"\'\]\[{}|\\^]+', re.I)
TRAILING = '.,;:!?\'")'

def extract_urls(text: str) -> list[str]:
    urls = []
    for raw in URL_RE.findall(text):
        url = raw.rstrip(TRAILING)
        # keep a final ')' if the URL contains an unmatched '('
        if raw.rstrip(TRAILING + ')').count('(') > url.count(')'):
            url += ')'
        urls.append(url)
    return list(dict.fromkeys(urls))   # dedupe, preserve order

with open("input.txt", encoding="utf-8") as f:
    for url in extract_urls(f.read()):
        print(url)

If the input is HTML, skip regex entirely and parse it properly:

from bs4 import BeautifulSoup

soup = BeautifulSoup(html, "html.parser")
links = {a["href"] for a in soup.find_all("a", href=True)}

Regex on HTML misses relative links (/about) and picks up URLs in scripts and comments; a parser gives you exactly the href values, which you can resolve against the base URL with urllib.parse.urljoin. For choosing the right way to target elements in parsed HTML, see CSS selectors vs XPath.

Which method when?

SituationBest method
One-off, any size, private dataBrowser extractor
Inside a shell pipelinegrep -oE 'https?://[^ ">]+' file
Recurring job, plain textPython regex above
Input is HTMLBeautifulSoup, not regex

One closing tip: whatever method you use, run the result through dedup after stripping tracking parameters, not before — ?utm_source=twitter and ?utm_source=newsletter versions of the same page should collapse to one URL, and they only will if you clean them first. (The browser tool applies the steps in the right order automatically.)

Try the free URL Extractor from Text →