/^/
HardNetworking7 min read

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.

#port-number#networking#tcp#udp#validation

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.

^(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)$
TokenMeaning
^Anchors the match to the start of the string
6553[0-5]Matches the top of the range, 65530 through 65535
655[0-2]\dMatches 65500 through 65529
65[0-4]\d\dMatches 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.

0 22 8080

Test Cases

Editable — add your own inputs to see if they pass.

InputExpectedResult
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')); // true

Common 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

EngineSupportedNotes
ChromeYes
FirefoxYes
SafariYes
EdgeYes
Node.jsYes