New blogMaking an AI Agent You Can Trust With Money

★ Web · regex

Regex for IPv4 Address

Matches IPv4 addresses with four octets from 0 to 255. Leading zeros like 01 are rejected, because some parsers read them as octal.

  • Runs in your browser
  • No signup

Try the ipv4 address pattern

Read it in plain English (best-effort)

  • ^start of a line
  • (?:start a group (not captured)
  • (?:start a group (not captured)
  • 25the text '25'
  • [0-5]one character from: 0–5
  • |or
  • 2the character '2'
  • [0-4]one character from: 0–4
  • \da digit (0–9)
  • |or
  • 1the character '1'
  • \da digit (0–9)
  • \da digit (0–9)
  • |or
  • [1-9]one character from: 1–9
  • ?the previous is optional
  • \da digit (0–9)
  • )end of group
  • .the character '.'
  • )end of group
  • {3}exactly 3 of the previous
  • (?:start a group (not captured)
  • 25the text '25'
  • [0-5]one character from: 0–5
  • |or
  • 2the character '2'
  • [0-4]one character from: 0–4
  • \da digit (0–9)
  • |or
  • 1the character '1'
  • \da digit (0–9)
  • \da digit (0–9)
  • |or
  • [1-9]one character from: 1–9
  • ?the previous is optional
  • \da digit (0–9)
  • )end of group
  • $end of a line

One sample per line works well with the m flag on anchored patterns.

Waiting for a pattern
01

The pattern, piece by piece

/^(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$/
Pattern explanation
PartWhat it does
25[0-5]250–255
2[0-4]\d200–249
1\d\d100–199
[1-9]?\d0–99 without a leading zero
(?:octet\.){3}three octets each followed by a dot
octet$the fourth octet ends the string
02

What it accepts and rejects

Every sample below is checked automatically in JavaScript and Python. The tester above is preloaded with all of them, one per line.

Should match
Should match
192.168.1.1✓
10.0.0.0✓
255.255.255.255✓
0.0.0.0✓
8.8.8.8✓
172.16.254.1✓
Should not match
Should not match
256.1.1.1✗
192.168.1✗
192.168.01.1✗
1.2.3.4.5✗
192.168.1.-1✗
a.b.c.d✗
03

Copy it into your code

RE2-safeNo lookarounds or backreferences, so the same pattern works in Go's RE2 engine and in Rust's regex crate.

const ipv4Re = /^(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$/;

export function isValidIpv4(value) {
  return ipv4Re.test(value.trim());
}
04

When not to use regex for this

If you need to know whether an address is private, loopback or in a CIDR range, parse it with net.ParseIP (Go), ipaddress (Python) or a library, then compare. Range logic in regex is unreadable.

05

Questions engineers actually ask

Why reject leading zeros like 192.168.01.1?
Some tools interpret 010 as octal (8), so the same string can mean different addresses. Rejecting them avoids ambiguity.
Does it match CIDR notation like 10.0.0.0/8?
No. Split on the slash and validate the prefix length (0–32) separately.
What is catastrophic backtracking?
Some patterns, usually nested quantifiers like (a+)+, make a backtracking engine try an exponential number of paths on input that almost matches. The tester stops any run after 300ms, so a bad pattern can't freeze your tab. In production, that same pattern can take down a server (a ReDoS attack).
06

More web patterns

07

More from the workbench

Fine print

Tools: on the house.
Engineer: by the hour.

The regex was free. Code that doesn't need one is the upgrade: typed schemas, validated once at the edge, trusted everywhere after.

I'm Himanshu, an AI and full-stack engineer. I build MVPs, AI agents and the growth plumbing around them for early-stage startups.