Twitter/X URL Regex
Matches a Twitter/X profile URL or an individual tweet (status) URL on either twitter.com or x.com, capturing the handle and optional tweet ID.
Regex Pattern
^https?:\/\/(?:www\.)?(?:twitter|x)\.com\/(\w{1,15})(?:\/status\/(\d+))?\/?$Pattern Breakdown
Hover over a token to see what it does.
| Token | Meaning |
|---|---|
| ^ | Anchors the match to the start of the string |
| https? | Matches http or https |
| :\/\/ | Literal :// scheme separator |
| (?:www\.)? | Optional www. subdomain prefix |
| (?:twitter|x)\.com\/ | Either the legacy twitter.com or current x.com host, followed by a slash |
| (\w{1,15}) | Capture group 1: the handle, 1 to 15 word characters matching Twitter's username length limit |
| (?:\/status\/(\d+))? | Optional /status/ segment with capture group 2 for the numeric tweet ID |
| \/?$ | Optional trailing slash, then end of string |
Detailed Explanation
What it does
This pattern matches both a bare profile URL like https://x.com/handle and a link to a specific tweet like https://twitter.com/handle/status/123456789, accepting either the legacy twitter.com domain or the current x.com domain. It captures the handle and, when present, the numeric tweet ID.
Why it works
The host alternation (?:twitter|x)\.com covers the platform's rebrand while keeping backward compatibility with existing links. The handle is bounded to \w{1,15}, matching Twitter/X's documented maximum username length, which helps reject non-profile paths that happen to start with a word-like segment but are actually longer, such as internal app routes. The optional /status/(\d+) group makes the tweet ID capture opt-in, so the same pattern serves both profile and tweet URLs.
Common use cases
- Validating a social media link field that accepts either the twitter.com or x.com domain
- Extracting a handle and tweet ID from a pasted link to fetch tweet details via the X API
- Normalizing links from either domain to a single canonical form during storage
- Filtering scraped URLs to isolate links to individual tweets versus profile pages
Edge cases
- Both twitter.com and x.com resolve successfully, reflecting the platform's 2023 rebrand
- A trailing slash after the handle or tweet ID is accepted because of the optional \/? before the end anchor
- Handles longer than 15 characters are rejected since \w{1,15} caps the length, matching the platform's real constraint
- Status links without a handle are not matched since the handle group is mandatory, unlike the tweet ID which is optional
- Reserved paths that aren't real handles, like /home or /search, would still technically match since this pattern doesn't maintain a reserved-word denylist
Limitations
- Does not exclude Twitter/X's reserved system routes (e.g. /home, /explore, /settings) from being treated as valid handles
- Does not validate that the numeric tweet ID corresponds to an actual existing tweet
- Does not match other X URL types such as media galleries, lists, or spaces
Interactive Tester
Edit the pattern or text below — matching runs live in your browser.
Test Cases
Editable — add your own inputs to see if they pass.
| Input | Expected | Result | |
|---|---|---|---|
| Pass | |||
| Pass | |||
| Pass | |||
| Pass | |||
| Pass | |||
| Pass | |||
| Pass |
Language Variants
Production-ready examples in 12 languages.
const twitterUrlRegex = /^https?:\/\/(?:www\.)?(?:twitter|x)\.com\/(\w{1,15})(?:\/status\/(\d+))?\/?$/;
const m = 'https://x.com/openai/status/123'.match(twitterUrlRegex);
console.log(m[1], m[2]); // 'openai' '123'Common Mistakes
Only matching twitter.com and rejecting valid x.com links after the platform's rebrand
Fix: Use a host alternation (?:twitter|x)\.com so both domains are accepted
Allowing handles of unbounded length, which lets non-profile paths slip through as false positives
Fix: Cap the handle with \w{1,15} to match Twitter/X's actual username length limit
Treating reserved routes like /home or /settings as valid handles
Fix: Maintain a denylist of reserved words and check captured handles against it after the regex match
Performance Notes
- The bounded handle quantifier \w{1,15} avoids unbounded backtracking compared to an open-ended + or *
- The optional status group only adds matching cost when a /status/ segment is actually present in the input
- Anchoring with ^ and $ avoids scanning arbitrary substrings for a match when validating a full URL string
Browser Compatibility
| Engine | Supported | Notes |
|---|---|---|
| Chrome | Yes | — |
| Firefox | Yes | — |
| Safari | Yes | — |
| Edge | Yes | — |
| Node.js | Yes | — |
Work with this pattern
Take this expression further — test it against your own data, adapt it in the builder, or read up on the syntax behind it.
Regex Tester
Test a regular expression against sample text and see every match highlighted live.
Regex Generator
Build a pattern by clicking blocks — no syntax memorisation required.
Regular Expressions Guide
What regex is, how the syntax works, and the mistakes that trip people up.
Regex Cheat Sheet
Every token, quantifier, and assertion on one printable page.
Python Regex Guide
The re module end to end — search, match, findall, groups, and substitution.
Regex Pattern Library
100+ ready-to-use patterns for email, URLs, dates, IPs, and more.