IPv4 Address Regular Expression – Free, Online, Private
Matches a dotted IPv4 address whose octets are between 0 and 255.
- 192.168.0.1
- 8.8.8.8
- 99.1.1.1
The pattern
Each octet is restricted to 0–255, and three literal dots separate four octets. 192.168.0.1 and 8.8.8.8 match. 999.1.1.1 does not, because 999 fails every branch of the octet alternation. 192.168.0 does not, because the fourth octet is missing. The pattern will still find an address inside a longer token such as 192.168.0.1.10 if you do not add boundaries. Put \b around it, or anchors, when the surrounding text is a log line full of version numbers.
The source is (?:(?: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). No flags are set. The match is case-sensitive, and ^ or $ mean the start and end of the whole input. Add m yourself in the tester if you paste several lines. The box under the title is a tester with this pattern and the sample already filled in. Edit either one. Nothing you type is uploaded. The same tester, without a preset, is the regex tool.
How to read it
The octet is an alternation, tried left to right. 25[0-5] is 250–255. 2[0-4]\d is 200–249. 1\d\d is 100–199. [1-9]?\d is 0–99, including a single 0. The order matters: if the two-digit branch came first, a number such as 255 could be partly consumed. The non-capturing group (?: ... \.){3} repeats 'octet plus dot' three times, and a final octet finishes the address. \d is a digit. Nothing in the pattern allows a leading plus or a space inside the address.
What it will not do
Leading zeros are matched by the last branch, so 192.168.001.001 matches even though some parsers treat a leading zero as octal and reject it. The pattern does not know about that debate. It also does not match IPv4-mapped IPv6, and it does not require the address to be the whole string. 255.255.255.255 matches, and so does 0.0.0.0. Both are syntactically fine and operationally special. Decide what your form should do with them after the match, not inside the expression.
A match is not a parsed value. An email pattern does not send mail, a UUID pattern does not allocate an id, and a password pattern does not store a password. When the next step needs a real parser, use one: the URL constructor, a date library, a semver library, or the converters on this site. The expression is the part you can see.
JavaScript, Python, and Go
The JavaScript snippet uses the RegExp constructor so the source does not have to be escaped for a literal slash. The Python snippet uses a normal string with the same escapes JSON would emit, which keeps \d as a regex digit class. Go's snippet uses a raw string. If the pattern contains a lookahead, the Go snippet says so and does not call MustCompile, because RE2 would reject it at runtime.
JavaScriptconst re = new RegExp("(?:(?: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)", "");
const found = text.match(re);
console.log(found ? found[0] : "no match");
Pythonimport re
pattern = re.compile("(?:(?: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)")
found = pattern.search(text)
print(found.group(0) if found else "no match")
Gopackage main
import (
"fmt"
"regexp"
)
func main() {
text := ""
re := regexp.MustCompile(`(?:(?: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)`)
fmt.Println(re.FindString(text))
}
Frequently asked questions
Does 999.1.1.1 match?
No. Each octet has to fall in 0–255. 999 matches none of the branches.
Are leading zeros allowed?
The pattern matches them. If your parser rejects 01 as octal, add a stricter branch or reject the match afterwards.
Will this find an address inside a sentence?
Yes. Add ^ and $, or word boundaries, when the whole input must be one address.
Does it match ports?
No. A trailing :443 is outside the match. Split the port off before you test if the field contains one.