TCP/UDP Port Number Regex
Validates that a string is a valid TCP or UDP port number in the full range 0 to 65535, rejecting values outside that range and leading zeros.
Regex Pattern
^(6553[0-5]|655[0-2]\d|65[0-4]\d\d|6[0-4]\d{3}|[1-5]\d{4}|[1-9]\d{0,3}|0)$Pattern Breakdown
Hover over a token to see what it does.
| Token | Meaning |
|---|---|
| ^ | Anchors the match to the start of the string |
| 6553[0-5] | Matches the top of the range, 65530 through 65535 |
| 655[0-2]\d | Matches 65500 through 65529 |
| 65[0-4]\d\d | Matches 65000 through 65499 |
| 6[0-4]\d{3} | Matches 60000 through 64999 |
| [1-5]\d{4} | Matches 10000 through 59999 |
| [1-9]\d{0,3} | Matches 1 through 9999 with no leading zero |
| $ | Anchors the match to the end of the string |
Detailed Explanation
What it does
This pattern validates that a string represents a valid port number, meaning an integer from 0 to 65535 inclusive, which is the range defined by the 16-bit port field used by TCP and UDP. It rejects numbers above 65535, negative numbers, non-numeric input, and numbers with leading zeros.
Why it works
Because a plain digit-count quantifier like \d{1,5} would also accept out-of-range values like 99999, the pattern instead uses a tiered alternation, ordered from the highest range down to the lowest, where each branch is a fixed-width pattern matching only the digit combinations valid for that magnitude: 6553[0-5] handles 65530-65535, 655[0-2]\d handles 65500-65529, 65[0-4]\d\d handles 65000-65499, 6[0-4]\d{3} handles 60000-64999, [1-5]\d{4} handles 10000-59999, and [1-9]\d{0,3} handles 1-9999 without a leading zero, with a final literal 0 for the zero port. Together these branches partition the full 0-65535 range exactly, so any number in range matches exactly one branch and any number outside it, like 65536 or 99999, matches none.
Common use cases
- Validating a port field in a network configuration form or CLI tool
- Sanity-checking a port value before passing it to a socket bind or connect call
- Parsing host:port strings and confirming the port segment is in range
- Filtering configuration files or firewall rules for malformed port entries
Edge cases
- Port 0 is valid and matched by the final literal alternative, representing a request for an ephemeral OS-assigned port in many APIs
- Port 65535, the maximum 16-bit unsigned value, is matched by the 6553[0-5] branch
- Values just above the range, like 65536, correctly fail to match any branch because no alternative extends that high
- Leading zeros, like 080, are rejected because every branch either starts with a non-zero digit or is the standalone literal 0
Limitations
- Does not distinguish between well-known ports (0-1023), registered ports (1024-49151), and dynamic/private ports (49152-65535), which some applications need to treat differently
- Does not verify that the port is actually available or in use on the host system
- Treats the input purely as text; the caller must ensure the value has already been extracted from a larger string like a URL or host:port pair
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 | |||
| Pass | |||
| Pass |
Language Variants
Production-ready examples in 12 languages.
const portRegex = /^(6553[0-5]|655[0-2]\d|65[0-4]\d\d|6[0-4]\d{3}|[1-5]\d{4}|[1-9]\d{0,3}|0)$/;
console.log(portRegex.test('8080')); // trueCommon Mistakes
Using a simple \d{1,5} pattern, which incorrectly accepts out-of-range values like 99999 or 70000
Fix: Use a tiered alternation like 6553[0-5]|655[0-2]\d|65[0-4]\d\d|... that precisely bounds each magnitude to the 0-65535 range
Forgetting to also validate the parsed integer in application code, relying on the regex alone even when the string is later converted with parseInt or similar
Fix: Treat the regex as input sanitization and still perform a numeric range check after parsing, especially if the value came from untrusted input
Allowing leading zeros such as 0080, which some systems misinterpret and which are not conventional port representations
Fix: Structure the alternation so every branch other than the standalone 0 requires a non-zero leading digit, as with [1-9]\d{0,3}
Performance Notes
- Ordering the alternation from the largest range down to the smallest lets the engine fail fast on clearly out-of-range high numbers without trying every branch
- Every branch has a fixed or tightly bounded digit count, so there is no catastrophic backtracking risk even on adversarial input
- For extremely hot code paths, parsing the string to an integer and comparing against 0 and 65535 numerically can be faster than regex, though the regex is convenient for form-level or config-file validation
Browser Compatibility
| Engine | Supported | Notes |
|---|---|---|
| Chrome | Yes | — |
| Firefox | Yes | — |
| Safari | Yes | — |
| Edge | Yes | — |
| Node.js | Yes | — |