Xác thực địa chỉ IPv4 bằng regexp


91

Tôi đã cố gắng lấy một regex hiệu quả để xác thực IPv4, nhưng không gặp nhiều may mắn. Có vẻ như tại một thời điểm tôi đã sử dụng nó (25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?(\.|$)){4}, nhưng nó tạo ra một số kết quả kỳ lạ:

$ grep --version
grep (GNU grep) 2.7
$ grep -E '\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?(\.|$)){4}\b' <<< 192.168.1.1
192.168.1.1
$ grep -E '\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?(\.|$)){4}\b' <<< 192.168.1.255
192.168.1.255
$ grep -E '\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?(\.|$)){4}\b' <<< 192.168.255.255
$ grep -E '\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?(\.|$)){4}\b' <<< 192.168.1.2555
192.168.1.2555

Tôi đã tìm kiếm để xem liệu câu hỏi này đã được hỏi và trả lời hay chưa, nhưng các câu trả lời khác dường như chỉ hiển thị cách xác định 4 nhóm từ 1-3 số hoặc không phù hợp với tôi.


12
Đừng quên rằng A, AB và ABC là các dạng địa chỉ IP hợp lệ cũng như ABCD Nghiêm túc. Hãy thử ping 2130706433ping 127.1cho một tiếng cười khúc khích.
dty

1
Biến thể của tôi trực tuyến regexr.com/39hqf
Sllouyssgort

Câu trả lời:


98

Bạn đã có một câu trả lời hiệu quả nhưng trong trường hợp bạn tò mò điều gì đã xảy ra với cách tiếp cận ban đầu của mình, câu trả lời là bạn cần dấu ngoặc đơn xung quanh sự thay thế của mình, nếu không thì câu trả lời (\.|$)chỉ bắt buộc nếu số lượng nhỏ hơn 200.

'\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}\b'
    ^                                    ^

26
điều này dường như cũng xác nhận những thứ như192.168.1.1.1
cwd

2
Có nên không : \b((?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(?:(?<!\.)\b|\.)){4}; tức là vì vậy nó kết thúc với một ranh giới từ chứ không phải với cuối dòng? Ngoài ra, ở đây, tôi đã đánh dấu các nhóm không chụp để tránh các nhóm phụ không mong muốn. NB: Điều này vẫn chưa tính đến nhận xét của @ dty vì tôi không quen với dạng IP đó; mặc dù anh ấy đúng rằng nó có vẻ hợp lệ.
JohnLBevan

Bạn có thể muốn thử điều này thay thế: ((1? \ D \ d? | 2 [0-4] \ d | 25 [0-5]) \.) {3} (1? \ D \ d? | 2 [0-4] \ d | 25 [0-5])
Morg.

Điều này hoạt động tốt đối với không chụp -\b(?:(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b
Appy

3
09.09.09.09được coi là một IP hợp lệ? Nó cũng được khớp bởi regex này. Nhưng ping ném ra thông báo lỗi như thế nào ping: cannot resolve 09.09.09.09: Unknown host. Tôi nghĩ có thể là khôn ngoan nếu giảm đối sánh xuống chỉ đối sánh ký hiệu dấu chấm-thập phân. Mục này thảo luận về các lỗi hàng đầu trong địa chỉ IP.
Ruifeng Ma

79
^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$

Chấp nhận :

127.0.0.1
192.168.1.1
192.168.1.255
255.255.255.255
0.0.0.0
1.1.1.01

Từ chối :

30.168.1.255.1
127.1
192.168.1.256
-1.2.3.4
1.1.1.1.
3...3

Thử trực tuyến với các bài kiểm tra đơn vị: https://www.debuggex.com/r/-EDZOqxTxhiTncN6/1


những gì về địa chỉ ip "3 ... 3"? 3 ... 3 được chấp nhận sử dụng regex này
Ankur Loriya

7
Còn 1.1.1.01 thì sao? Nó có được coi là một địa chỉ IPv4 hợp lệ không? Cảm ơn.
odieatla

regexp 1.1.1.01 này được coi là địa chỉ IPv4 HỢP LỆ. Đơn vị trực tuyến kiểm tra debuggex.com/r/-EDZOqxTxhiTncN6/1
Sllouyssgort

bằng cách này ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}$nhận được cùng một kết quả debuggex.com/r/mz_-0dEm3wseIKqK , khá giống với @ Mark Byers câu trả lời
Sllouyssgort

@PriteshAcharya Hoạt động tốt ở đây.
Kid Diamond

35

Phiên bản mới nhất, ngắn nhất, ít đọc nhất ( 55 ký tự )

^((25[0-5]|(2[0-4]|1[0-9]|[1-9]|)[0-9])(\.(?!$)|$)){4}$

Phiên bản này tìm trường hợp 250-5, sau đó nó khéo léo HOẶC tất cả các trường hợp có thể có cho 200-249 100-199 10-99các trường hợp. Lưu ý rằng |)phần này không phải là một sai lầm, mà thực sự OR là trường hợp cuối cùng cho phạm vi 0-9. Tôi cũng đã bỏ qua phần nhóm ?:không bắt được vì chúng tôi không thực sự quan tâm đến các mục đã chụp, chúng sẽ không bị bắt theo cách nào đó nếu chúng tôi không có một trận đấu đầy đủ ngay từ đầu.

Phiên bản cũ và ngắn hơn (ít đọc hơn) ( 63 ký tự )

^(?:(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(?!$)|$)){4}$

Phiên bản cũ hơn (có thể đọc được) ( 70 ký tự )

^(?:(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(\.(?!$)|$)){4}$

Nó sử dụng lookahead phủ định (?!)để loại bỏ trường hợp ip có thể kết thúc bằng.

Câu trả lời cũ nhất ( 115 ký tự )

^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}
    (?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$

Tôi nghĩ đây là regex chính xác và nghiêm ngặt nhất, nó không chấp nhận những thứ giống 000.021.01.0.như hầu hết các câu trả lời khác ở đây làm và yêu cầu regex bổ sung để từ chối các trường hợp tương tự như câu đó - tức là 0số bắt đầu và ip kết thúc bằng.


Đây là câu trả lời đúng duy nhất trong chủ đề này cho đến nay. Những người khác bỏ lỡ các địa chỉ như vậy 0.0.0.0hoặc chấp nhận ký hiệu bát phân / thập phân hỗn hợp như 033.033.33.033hoặc thậm chí cho phép 999.999.999.999. Làm thế nào về regex này ngắn hơn 10 ký tự so với câu trả lời này:(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])
anneb

1
@tinmarino Tôi đã hoàn nguyên chỉnh sửa của bạn vì nó cho phép những thứ như 192.168.000.1 không phải là địa chỉ hợp lệ. Bất cứ ai muốn chỉnh sửa câu trả lời này, vui lòng bình luận trước ở đây để tránh những vấn đề như thế này - Tôi thường trả lời khá nhanh. Tất nhiên, luôn tìm kiếm một giải pháp ngắn hơn / tốt hơn.
Danail Gabenski

1
@DanailGabenski (và khác) cho bộ nhớ, bạn đã giải quyết nó [01]?[0-9][0-9]?bằng cách thay thế cuối cùng bởi 1[0-9]{2}|[1-9]?[0-9]vì bạn không thích số 0 đứng đầu . Cảm ơn một lần nữa! Tôi sẽ giữ giải pháp của bạn trong hành lý chủ regex của tôi.
Tinmarino

1
@tinmarino vâng, định dạng dấu chấm-thập phân đã trở thành tiêu chuẩn cho ipv4, mặc dù không được chấp nhận chính thức, vui lòng xem phần sau . Cụ thể là điểm 3, nơi một dự thảo đã được đề xuất nhưng đã hết hạn. Một lý do thứ yếu cho việc xác thực quá nghiêm ngặt là khi hiển thị trong giao diện người dùng, ip có các số không thập phân như 023 thay vì 23 khiến người dùng cho rằng đây là một sai lầm / lỗi. Nó cũng dẫn đến những khó khăn với xác minh / bảo mật vì 023 cần được chuyển đổi thành 23 để tránh trùng lặp, v.v. Cảm ơn bạn đã cố gắng làm mọi thứ tốt hơn!
Danail Gabenski

1
Bạn có thể làm cho nó ngắn hơn bằng cách thanh toán ra [0-9]cho 2[0-4], 1và ngắn hơn trường hợp. ^(?:(25[0-5]|(?:2[0-4]|1[0-9]|[1-9]|)[0-9])(\.(?!$)|$)){4}$
Clayton Singh

12

Địa chỉ IPv4 (bắt chính xác) Đối sánh từ 0.0.0.0 đến 255.255.255.255 Sử dụng regex này để khớp số IP với độ chính xác. Mỗi số trong số 4 số được lưu trữ thành một nhóm chụp, vì vậy bạn có thể truy cập chúng để xử lý thêm.

\b
(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.
(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.
(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.
(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)
\b

lấy từ thư viện JGsoft RegexBuddy

Chỉnh sửa: (\.|$)phần này có vẻ wierd


2
Đẹp! Tôi đã thực hiện một sửa đổi hiệu quả hơn mà dường như hoạt động: "\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$){4}\b- cảm ơn!
Matthieu Cartier

2
@MatthieuCartier mẫu biểu thức chính hiệu quả của bạn không làm việc cho tôi,
R__raki__

255.255.255.000 không phải là một địa chỉ IP hợp lệ
Stéphane Grillon

6

Tôi đang tìm kiếm thứ gì đó tương tự cho địa chỉ IPv4 - một regex cũng đã ngăn các địa chỉ ip riêng thường được sử dụng không được xác thực (192.168.xy, 10.xyz, 172.16.xy) vì vậy đã sử dụng cách nhìn tiêu cực để thực hiện điều này:

(?!(10\.|172\.(1[6-9]|2\d|3[01])\.|192\.168\.).*)
(?!255\.255\.255\.255)(25[0-5]|2[0-4]\d|[1]\d\d|[1-9]\d|[1-9])
(\.(25[0-5]|2[0-4]\d|[1]\d\d|[1-9]\d|\d)){3}

(Tất nhiên, chúng phải nằm trên một dòng, được định dạng cho mục đích dễ đọc trên 3 dòng riêng biệt) Hình ảnh hóa biểu thức chính quy

Bản trình diễn gỡ lỗi

Nó có thể không được tối ưu hóa về tốc độ, nhưng hoạt động tốt khi chỉ tìm kiếm các địa chỉ internet 'thực'.

Những điều sẽ (và nên) thất bại:

0.1.2.3         (0.0.0.0/8 is reserved for some broadcasts)
10.1.2.3        (10.0.0.0/8 is considered private)
172.16.1.2      (172.16.0.0/12 is considered private)
172.31.1.2      (same as previous, but near the end of that range)
192.168.1.2     (192.168.0.0/16 is considered private)
255.255.255.255 (reserved broadcast is not an IP)
.2.3.4
1.2.3.
1.2.3.256
1.2.256.4
1.256.3.4
256.2.3.4
1.2.3.4.5
1..3.4

Các IP sẽ (và nên) hoạt động:

1.0.1.0         (China)
8.8.8.8         (Google DNS in USA)
100.1.2.3       (USA)
172.15.1.2      (USA)
172.32.1.2      (USA)
192.167.1.2     (Italy)

Được cung cấp trong trường hợp bất kỳ ai khác đang tìm kiếm xác thực 'địa chỉ IP Internet không bao gồm các địa chỉ chung'


5

Tôi nghĩ rằng nhiều người đọc bài đăng này sẽ tìm kiếm các cụm từ thông dụng đơn giản hơn, ngay cả khi chúng khớp với một số địa chỉ IP không hợp lệ về mặt kỹ thuật. (Và, như đã lưu ý ở những nơi khác, regex có thể không phải là công cụ phù hợp để xác thực đúng địa chỉ IP.)

Loại bỏ ^và, nếu có thể, thay thế $bằng \b, nếu bạn không muốn khớp với đầu / cuối dòng.

Biểu thức chính quy cơ bản (BRE) (được thử nghiệm trên GNU grep, GNU sed và vim):

/^[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+$/

Biểu thức chính quy mở rộng (ERE):

/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/

hoặc là:

/^([0-9]+(\.|$)){4}/

Biểu thức chính quy tương thích với Perl (PCRE) (được thử nghiệm trên Perl 5.18):

/^\d+\.\d+\.\d+\.\d+$/

hoặc là:

/^(\d+(\.|$)){4}/

Ruby (được thử nghiệm trên Ruby 2.1):

Mặc dù được cho là PCRE, Ruby vì bất cứ lý do gì đã cho phép regex này không được Perl 5.18 cho phép:

/^(\d+[\.$]){4}/

Các bài kiểm tra của tôi cho tất cả những thứ này đều trực tuyến ở đây .


3

Điều này dài hơn một chút so với một số nhưng đây là những gì tôi sử dụng để khớp với địa chỉ IPv4. Đơn giản không có thỏa hiệp.

^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])$

3

Các câu trả lời trên là hợp lệ nhưng điều gì xảy ra nếu địa chỉ ip không nằm ở cuối dòng và nằm giữa văn bản .. Regex này thậm chí sẽ hoạt động trên đó.

mã: '\b((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.)){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\b'

tệp văn bản đầu vào:

ip address 0.0.0.0 asfasf
 sad sa 255.255.255.255 cvjnzx
zxckjzbxk  999.999.999.999 jshbczxcbx
sjaasbfj 192.168.0.1 asdkjaksb
oyo 123241.24121.1234.3423 yo
yo 0000.0000.0000.0000 y
aw1a.21asd2.21ad.21d2
yo 254.254.254.254 y0
172.24.1.210 asfjas
200.200.200.200
000.000.000.000
007.08.09.210
010.10.30.110

văn bản đầu ra:

0.0.0.0
255.255.255.255
192.168.0.1
254.254.254.254
172.24.1.210
200.200.200.200

1
Điều này đã được đánh dấu tiêu cực, cho đến khi tôi bỏ phiếu cho nó. Tôi đã cố gắng làm chính xác điều này trong (nhiều giờ hơn tôi muốn thừa nhận). Nó sẽ không chụp một dòng có nhiều hơn một dấu chấm-phần tư trên một dòng, nhưng đối với trường hợp sử dụng của tôi, tôi có thể sống với điều đó. Đây là một câu trả lời xuất sắc, nó cần nhiều phiếu bầu hơn!
anastrophe

3

'' 'Mã này phù hợp với tôi, và đơn giản như vậy.

Ở đây tôi đã lấy giá trị của ip và tôi đang cố gắng khớp nó với regex.

ip="25.255.45.67"    

op=re.match('(\d+).(\d+).(\d+).(\d+)',ip)

if ((int(op.group(1))<=255) and (int(op.group(2))<=255) and int(op.group(3))<=255) and (int(op.group(4))<=255)):

print("valid ip")

else:

print("Not valid")

Điều kiện trên kiểm tra nếu giá trị vượt quá 255 cho tất cả 4 octet thì nó không phải là giá trị hợp lệ. Nhưng trước khi áp dụng điều kiện, chúng ta phải chuyển chúng thành số nguyên vì giá trị nằm trong một chuỗi.

nhóm (0) in kết quả phù hợp, Trong khi nhóm (1) in giá trị phù hợp đầu tiên và ở đây là "25", v.v. ''


Chào mừng bạn đến với StackOverflow. Nếu bạn có thể dành một số từ về lý do tại sao câu trả lời của bạn nên giải quyết vấn đề OP, thì thật tuyệt. Câu trả lời chỉ có mã thường là câu trả lời tồi vì chúng không giúp các đồng nghiệp lập trình viên hiểu được họ đã làm gì sai.
Davide Vitali

Sử dụng thụt thích hợp trong mã của bạn để làm cho nó có thể đọc được cho người sử dụng
Syed Mehtab Hassan


2

Đối với số từ 0 đến 255, tôi sử dụng regex này:

(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))

Trên regex sẽ khớp với số nguyên từ 0 đến 255, nhưng không khớp với 256.

Vì vậy, đối với IPv4, tôi sử dụng regex này:

^(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))((\.(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))){3})$

Nó nằm trong cấu trúc này: ^(N)((\.(N)){3})$trong đó N là regex được sử dụng để khớp số từ 0 đến 255.
Regex này sẽ khớp với IP như bên dưới:

0.0.0.0
192.168.1.2

nhưng không phải những người dưới đây:

10.1.0.256
1.2.3.
127.0.1-2.3

Đối với IPv4 CIDR (Định tuyến liên miền không phân lớp), tôi sử dụng regex này:

^(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))((\.(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))){3})\/(([0-9])|([12][0-9])|(3[0-2]))$

Nó nằm trong cấu trúc này: ^(N)((\.(N)){3})\/M$trong đó N là regex được sử dụng để khớp với số từ 0 đến 255 và M là regex được sử dụng để khớp với số từ 0 đến 32.
Regex này sẽ khớp với CIDR như dưới đây:

0.0.0.0/0
192.168.1.2/32

nhưng không phải những người dưới đây:

10.1.0.256/16
1.2.3./24
127.0.0.1/33

Và đối với danh sách IPv4 CIDR, "10.0.0.0/16", "192.168.1.1/32"tôi sử dụng regex này:

^("(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))((\.(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))){3})\/(([0-9])|([12][0-9])|(3[0-2]))")((,([ ]*)("(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))((\.(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))){3})\/(([0-9])|([12][0-9])|(3[0-2]))"))*)$

Nó nằm trong cấu trúc này: ^(“C”)((,([ ]*)(“C”))*)$trong đó C là regex được sử dụng để khớp với CIDR (như 0.0.0.0/0).
Regex này sẽ khớp với danh sách CIDR như bên dưới:

“10.0.0.0/16”,”192.168.1.2/32”, “1.2.3.4/32”

nhưng không phải những người dưới đây:

“10.0.0.0/16” 192.168.1.2/32 “1.2.3.4/32”

Có lẽ nó có thể ngắn hơn nhưng đối với tôi, nó rất dễ hiểu đối với tôi.

Hy vọng nó giúp!


Chào mừng bạn đến với SO, chúng tôi đánh giá cao ý kiến ​​đóng góp của bạn! Bạn có thể vui lòng giải thích một chút về những gì các regex khác nhau đang làm (đặc biệt là cái cuối cùng)?
B - rian

1

Tôi đã quản lý để tạo ra một regex từ tất cả các câu trả lời khác.

(25[0-5]|2[0-4][0-9]|[1][0-9][0-9]|[1-9][0-9]|[0-9]?)(\.(25[0-5]|2[0-4][0-9]|[1][0-9][0-9]|[1-9][0-9]|[0-9]?)){3}

Theo tiêu chuẩn ethernet IEEE 802.x, không được phép xác nhận IP là dải IP 0.xxx >>> - IP không hợp lệ. # 1.Dải IP bắt đầu từ 1.xxx đến 126.xxx >>>> có thể được phép cấu hình. # 2.Dải IP 127.xxx >>>> không được phép - IP không hợp lệ. # 3.Dải IP 128.xxx đến 223.xxx >> có thể được phép cấu hình. cách tốt hơn để xử lý được đề xuất như sau: ^ (22 [0-3] | 2 [0-1] [0-9] | [1] [0-9] [0-9]? | [1-9 ] [0-9] | [1-9]) \. (25 [0-5] | 2 [0-4] [0-9] | [01]? [0-9] [0-9]? ) \. (25 [0-5] | 2 [0-4] [0-9] | [01]? [0-9] [0-9]?) \. (25 [0-4] | 2 [0-4] [0-9] | [01]? [0-9] [0-9]?) $
Yogesh Aggarwal

1

Với mặt nạ mạng con:

^$|([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\
.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\
.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\
.([01]?\\d\\d?|2[0-4]\\d|25[0-5])
((/([01]?\\d\\d?|2[0-4]\\d|25[0-5]))?)$

1
(((25[0-5])|(2[0-4]\d)|(1\d{2})|(\d{1,2}))\.){3}(((25[0-5])|(2[0-4]\d)|(1\d{2})|(\d{1,2})))

Kiểm tra để tìm kết quả phù hợp trong văn bản, https://regex101.com/r/9CcMEN/2

Sau đây là các quy tắc xác định các kết hợp hợp lệ trong mỗi số của một địa chỉ IP:

  • Bất kỳ số có một hoặc hai chữ số.
  • Bất kỳ số có ba chữ số nào bắt đầu bằng 1.

  • Bất kỳ số có ba chữ số nào bắt đầu bằng 2nếu chữ số thứ hai 0 đi qua 4.

  • Bất kỳ số có ba chữ số nào bắt đầu bằng 25nếu chữ số thứ ba 0 đi qua 5.

Hãy bắt đầu với (((25[0-5])|(2[0-4]\d)|(1\d{2})|(\d{1,2}))\.), một bộ bốn biểu thức con lồng nhau và chúng ta sẽ xem xét chúng theo thứ tự ngược lại. (\d{1,2})khớp với bất kỳ số một hoặc hai chữ số hoặc số 0thông qua 99. (1\d{2})khớp với bất kỳ số có ba chữ số nào bắt đầu bằng 1( 1theo sau bởi hai chữ số bất kỳ) hoặc các số cho 100đến hết 199. (2[0-4]\d)khớp với các số 200thông qua 249. (25[0-5])khớp với các số 250thông qua 255. Mỗi biểu thức con này được bao trong một biểu thức con khác với một biểu thức con |nằm giữa mỗi biểu thức (để một trong bốn biểu thức con phải khớp nhau, không phải tất cả). Sau khi phạm vi số \.khớp với nhau .và sau đó là toàn bộ chuỗi (tất cả các tùy chọn số cộng với\.) được bao gồm trong một biểu thức con khác và được lặp lại ba lần bằng cách sử dụng {3}. Cuối cùng, dải số được lặp lại (lần này không có dấu \.) để khớp với số địa chỉ IP cuối cùng. Bằng cách giới hạn từng số trong bốn số ở các giá trị giữa 0255, mẫu này thực sự có thể khớp với các địa chỉ IP hợp lệ và từ chối các địa chỉ không hợp lệ.

Trích từ: Ben Forta. “Học các Cụm từ Thông dụng”.


Nếu không có ký tự nào được muốn ở đầu địa chỉ IP và ở cuối, ^và các $ký tự siêu phải được sử dụng tương ứng.

^(((25[0-5])|(2[0-4]\d)|(1\d{2})|(\d{1,2}))\.){3}(((25[0-5])|(2[0-4]\d)|(1\d{2})|(\d{1,2})))$

Kiểm tra để tìm kết quả phù hợp trong văn bản, https://regex101.com/r/uAP31A/1


1

Tôi đã cố gắng làm cho nó đơn giản và ngắn gọn hơn một chút.

^(([01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}([01]?\d{1,2}|2[0-4]\d|25[0-5])$

Nếu bạn đang tìm kiếm java / kotlin:

^(([01]?\\d{1,2}|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d{1,2}|2[0-4]\\d|25[0-5])$

Nếu ai đó muốn biết nó hoạt động như thế nào thì đây là lời giải thích. Nó thực sự rất đơn giản. Cứ thử đi: p:

 1. ^.....$: '^' is the starting and '$' is the ending.

 2. (): These are called a group. You can think of like "if" condition groups.

 3. |: 'Or' condition - as same as most of the programming languages.

 4. [01]?\d{1,2}: '[01]' indicates one of the number between 0 and 1. '?' means '[01]' is optional. '\d' is for any digit between 0-9 and '{1,2}' indicates the length can be between 1 and 2. So here the number can be 0-199.

 5. 2[0-4]\d: '2' is just plain 2. '[0-4]' means a number between 0 to 4. '\d' is for any digit between 0-9. So here the number can be 200-249.

 6. 25[0-5]: '25' is just plain 25. '[0-5]' means a number between 0 to 5. So here the number can be 250-255.

 7. \.: It's just plan '.'(dot) for separating the numbers.

 8. {3}: It means the exact 3 repetition of the previous group inside '()'.

 9. ([01]?\d{1,2}|2[0-4]\d|25[0-5]): Totally same as point 2-6

Về mặt toán học, nó giống như:

(0-199 OR 200-249 OR 250-255).{Repeat exactly 3 times}(0-199 OR 200-249 OR 250-255)

Vì vậy, như bạn có thể thấy thông thường, đây là mẫu cho địa chỉ IP. Tôi hy vọng nó sẽ giúp hiểu một chút về Biểu thức chính quy. : p


1

Tôi đã cố gắng làm cho nó đơn giản và ngắn gọn hơn một chút.

^ (([01]? \ D {1,2} | 2 [0-4] \ d | 25 [0-5]).) {3} ([01]? \ D {1,2} | 2 [0-4] \ d | 25 [0-5]) $

Nếu bạn đang tìm kiếm java / kotlin:

^ (([01]? \ D {1,2} | 2 [0-4] \ d | 25 [0-5]) \.) {3} ([01]? \ D {1,2} | 2 [0-4] \ d | 25 [0-5]) $

Nếu ai đó muốn biết nó hoạt động như thế nào thì đây là lời giải thích. Nó thực sự rất đơn giản. Cứ thử đi: p:

 1. ^.....$: '^' is the starting and '$' is the ending.

 2. (): These are called a group. You can think of like "if" condition groups.

 3. |: 'Or' condition - as same as most of the programming languages.

 4. [01]?\d{1,2}: '[01]' indicates one of the number between 0 and 1. '?' means '[01]' is optional. '\d' is for any digit between 0-9 and '{1,2}' indicates the length can be between 1 and 2. So here the number can be 0-199.

 5. 2[0-4]\d: '2' is just plain 2. '[0-4]' means a number between 0 to 4. '\d' is for any digit between 0-9. So here the number can be 200-249.

 6. 25[0-5]: '25' is just plain 25. '[0-5]' means a number between 0 to 5. So here the number can be 250-255.

 7. \.: It's just plan '.'(dot) for separating the numbers.

 8. {3}: It means the exact 3 repetition of the previous group inside '()'.

 9. ([01]?\d{1,2}|2[0-4]\d|25[0-5]): Totally same as point 2-6

Về mặt toán học, nó giống như:

(0-199 OR 200-249 OR 250-255).{Repeat exactly 3 times}(0-199 OR 200-249 OR 250-255)

Vì vậy, như bạn có thể thấy thông thường, đây là mẫu cho địa chỉ IP. Tôi hy vọng nó sẽ giúp hiểu một chút về Biểu thức chính quy. : p


0
    const char*ipv4_regexp = "\\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\."
    "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\."
    "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\."
    "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b";

Tôi đã điều chỉnh biểu thức chính quy được lấy từ thư viện JGsoft RegexBuddy sang ngôn ngữ C (regcomp / regexec) và tôi phát hiện ra nó hoạt động nhưng có một chút vấn đề trong một số hệ điều hành như Linux. Biểu thức chính quy đó chấp nhận địa chỉ ipv4 như 192.168.100.009 trong đó 009 trong Linux được coi là một giá trị bát phân nên địa chỉ không phải là địa chỉ bạn nghĩ. Tôi đã thay đổi biểu thức chính quy đó như sau:

    const char* ipv4_regex = "\\b(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\."
           "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\."
           "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\."
           "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\b";

sử dụng expressione thông thường hiện tại 192.168.100.009 không phải là địa chỉ ipv4 hợp lệ trong khi 192.168.100.9 là được.

Tôi cũng đã sửa đổi một biểu thức chính quy cho địa chỉ multicast và nó như sau:

    const char* mcast_ipv4_regex = "\\b(22[4-9]|23[0-9])\\."
                        "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\."
                        "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9]?)\\."
                        "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\b";

Tôi nghĩ rằng bạn phải điều chỉnh cụm từ thông dụng với ngôn ngữ bạn đang sử dụng để phát triển ứng dụng của mình

Tôi đặt một ví dụ trong java:

    package utility;

    import java.util.regex.Matcher;
    import java.util.regex.Pattern;

    public class NetworkUtility {

        private static String ipv4RegExp = "\\b(?:(?: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?)\\b";

        private static String ipv4MulticastRegExp = "2(?:2[4-9]|3\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d?|0)){3}";

        public NetworkUtility() {

        }

        public static boolean isIpv4Address(String address) {
            Pattern pattern = Pattern.compile(ipv4RegExp);
            Matcher matcher = pattern.matcher(address);

            return matcher.matches();
        }

        public static boolean isIpv4MulticastAddress(String address) {
             Pattern pattern = Pattern.compile(ipv4MulticastRegExp);
             Matcher matcher = pattern.matcher(address);

             return matcher.matches();
        }
    }

0
-bash-3.2$ echo "191.191.191.39" | egrep 
  '(^|[^0-9])((2([6-9]|5[0-5]?|[0-4][0-9]?)?|1([0-9][0-9]?)?|[3-9][0-9]?|0)\.{3}
     (2([6-9]|5[0-5]?|[0-4][0-9]?)?|1([0-9][0-9]?)?|[3-9][0-9]?|0)($|[^0-9])'

>> 191.191.191.39

(Đây là DFA khớp với toàn bộ không gian bổ trợ (bao gồm cả chương trình phát sóng, v.v.) không có gì khác.


0

Tôi nghĩ cái này là ngắn nhất.

^(([01]?\d\d?|2[0-4]\d|25[0-5]).){3}([01]?\d\d?|2[0-4]\d|25[0-5])$

0

Tôi thấy mẫu này rất hữu ích, hơn nữa nó cho phép các ký hiệu ipv4 khác nhau.

mã mẫu sử dụng python:

    def is_valid_ipv4(ip4):
    """Validates IPv4 addresses.
    """
    import re
    pattern = re.compile(r"""
        ^
        (?:
          # Dotted variants:
          (?:
            # Decimal 1-255 (no leading 0's)
            [3-9]\d?|2(?:5[0-5]|[0-4]?\d)?|1\d{0,2}
          |
            0x0*[0-9a-f]{1,2}  # Hexadecimal 0x0 - 0xFF (possible leading 0's)
          |
            0+[1-3]?[0-7]{0,2} # Octal 0 - 0377 (possible leading 0's)
          )
          (?:                  # Repeat 0-3 times, separated by a dot
            \.
            (?:
              [3-9]\d?|2(?:5[0-5]|[0-4]?\d)?|1\d{0,2}
            |
              0x0*[0-9a-f]{1,2}
            |
              0+[1-3]?[0-7]{0,2}
            )
          ){0,3}
        |
          0x0*[0-9a-f]{1,8}    # Hexadecimal notation, 0x0 - 0xffffffff
        |
          0+[0-3]?[0-7]{0,10}  # Octal notation, 0 - 037777777777
        |
          # Decimal notation, 1-4294967295:
          429496729[0-5]|42949672[0-8]\d|4294967[01]\d\d|429496[0-6]\d{3}|
          42949[0-5]\d{4}|4294[0-8]\d{5}|429[0-3]\d{6}|42[0-8]\d{7}|
          4[01]\d{8}|[1-3]\d{0,9}|[4-9]\d{0,8}
        )
        $
    """, re.VERBOSE | re.IGNORECASE)
    return pattern.match(ip4) <> None

0
((\.|^)(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0$)){4}

Regex này sẽ không chấp nhận 08.8.8.8 hoặc 8.08.8.8 hoặc 8.8.08.8 hoặc 8.8.8.08


cái này bỏ lỡ ví dụ 127.0.0.1 và 0.0.0.0
anneb

^ ((\. | ^) (25 [0-5] | 2 [0-4] [0-9] | 1 [0-9] [0-9] | [1-9] [0-9] ? | [0-9]? | 0)) ((\. | ^) (25 [0-5] | 2 [0-4] [0-9] | 1 [0-9] [0-9] | [1-9] [0-9]? | 0)) {2}. ((25 [0-5] | 2 [0-4] [0-9] | 1 [0-9] [0- 9] | [1-9] [0-9]? | 0) $)
sudistack

1
Theo thông số kỹ thuật thì việc từ chối các số 0 ở đầu là đúng.
John Haugeland

0

Tìm các địa chỉ IP hợp lệ miễn là IP được bao quanh bất kỳ ký tự nào ngoài các chữ số (phía sau hoặc phía trước IP). 4 Phụ đề đã tạo: $ + {đầu tiên}. $ + {Thứ hai}. $ + {Thứ ba}. $ + {Thứ tư}

Find String:
#any valid IP address
(?<IP>(?<![\d])(?<first>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<second>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<third>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<forth>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))(?![\d]))
#only valid private IP address RFC1918
(?<IP>(?<![\d])(:?(:?(?<first>10)[\.](?<second>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5])))|(:?(?<first>172)[\.](?<second>(:?1[6-9])|(:?2[0-9])|(:?3[0-1])))|(:?(?<first>192)[\.](?<second>168)))[\.](?<third>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<forth>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))(?![\d]))

Notepad++ Replace String Option 1: Replaces the whole IP (NO Change):
$+{IP}

Notepad++ Replace String Option 2: Replaces the whole IP octect by octect (NO Change)
$+{first}.$+{second}.$+{third}.$+{forth}

Notepad++ Replace String Option 3: Replaces the whole IP octect by octect (replace 3rd octect value with 0)
$+{first}.$+{second}.0.$+{forth}
NOTE: The above will match any valid IP including 255.255.255.255 for example and change it to 255.255.0.255 which is wrong and not very useful of course.

Thay thế một phần của mỗi octect bằng một giá trị thực tế, tuy nhiên, bạn có thể xây dựng tính năng tìm và thay thế của riêng mình thực sự hữu ích để cải thiện IP trong tệp văn bản:

for example replace the first octect group of the original Find regex above:
(?<first>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))
with
(?<first>10)

and
(?<second>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))
with
(?<second>216)
and you are now matching addresses starting with first octect 192 only

Find on notepad++:
(?<IP>(?<![\d])(?<first>10)[\.](?<second>216)[\.](?<third>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<forth>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))(?![\d]))

Bạn vẫn có thể thực hiện Thay thế bằng cách sử dụng các nhóm tham chiếu ngược theo cùng một kiểu như trước đây.

Bạn có thể biết cách kết hợp ở trên dưới đây:

cat ipv4_validation_test.txt
Full Match:
0.0.0.1
12.108.1.34
192.168.1.1
10.249.24.212
10.216.1.212
192.168.1.255
255.255.255.255
0.0.0.0


Partial Match (IP Extraction from line)
30.168.1.0.1
-1.2.3.4
sfds10.216.24.23kgfd
da11.15.112.255adfdsfds
sfds10.216.24.23kgfd


NO Match
1.1.1.01
3...3
127.1.
192.168.1..
192.168.1.256
da11.15.112.2554adfdsfds
da311.15.112.255adfdsfds

Sử dụng grep, bạn có thể xem kết quả bên dưới:

From grep:
grep -oP '(?<IP>(?<![\d])(?<first>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<second>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<third>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<forth>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))(?![\d]))' ipv4_validation_test.txt
0.0.0.1
12.108.1.34
192.168.1.1
10.249.24.212
10.216.1.212
192.168.1.255
255.255.255.255
0.0.0.0
30.168.1.0
1.2.3.4
10.216.24.23
11.15.112.255
10.216.24.23


grep -P '(?<IP>(?<![\d])(?<first>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<second>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<third>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<forth>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))(?![\d]))' ipv4_validation_test.txt
0.0.0.1
12.108.1.34
192.168.1.1
10.249.24.212
10.216.1.212
192.168.1.255
255.255.255.255
0.0.0.0
30.168.1.0.1
-1.2.3.4
sfds10.216.24.23kgfd
da11.15.112.255adfdsfds
sfds10.216.24.23kgfd


#matching ip addresses starting with 10.216
grep -oP '(?<IP>(?<![\d])(?<first>10)[\.](?<second>216)[\.](?<third>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<forth>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))(?![\d]))' ipv4_validation_test.txt
10.216.1.212
10.216.24.23
10.216.24.23

0

Địa chỉ IPv4 là một thứ rất phức tạp.

Lưu ý : Thụt lề và lót chỉ nhằm mục đích minh họa và không tồn tại trong RegEx thực.

\b(
  ((
    (2(5[0-5]|[0-4][0-9])|1[0-9]{2}|[1-9]?[0-9])
  |
    0[Xx]0*[0-9A-Fa-f]{1,2}
  |
    0+[1-3]?[0-9]{1,2}
  )\.){1,3}
  (
    (2(5[0-5]|[0-4][0-9])|1[0-9]{2}|[1-9]?[0-9])
  |
    0[Xx]0*[0-9A-Fa-f]{1,2}
  |
    0+[1-3]?[0-9]{1,2}
  )
|
  (
    [1-3][0-9]{1,9}
  |
    [1-9][0-9]{,8}
  |
    (4([0-1][0-9]{8}
      |2([0-8][0-9]{7}
        |9([0-3][0-9]{6}
          |4([0-8][0-9]{5}
            |9([0-5][0-9]{4}
              |6([0-6][0-9]{3}
                |7([0-1][0-9]{2}
                  |2([0-8][0-9]{1}
                    |9([0-5]
    ))))))))))
  )
|
  0[Xx]0*[0-9A-Fa-f]{1,8}
|
  0+[1-3]?[0-7]{,10}
)\b

Các địa chỉ IPv4 này được xác thực bởi RegEx ở trên.

127.0.0.1
2130706433
0x7F000001
017700000001
0x7F.0.0.01 # Mixed hex/dec/oct
000000000017700000001 # Have as many leading zeros as you want
0x0000000000007F000001 # Same as above
127.1
127.0.1

Chúng bị từ chối.

256.0.0.1
192.168.1.099 # 099 is not a valid number
4294967296 # UINT32_MAX + 1
0x100000000
020000000000

0

^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\\.)){3}+((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))$


Ở trên sẽ là regex cho địa chỉ ip như: 221.234.000.112 cũng cho 221.234.0.112, 221.24.03.112, 221.234.0.1


Bạn có thể hình dung tất cả các loại địa chỉ như trên


0

Tôi sẽ sử dụng PCRE và definetừ khóa:

/^
 ((?&byte))\.((?&byte))\.((?&byte))\.((?&byte))$
 (?(DEFINE)
     (?<byte>25[0-5]|2[0-4]\d|[01]?\d\d?))
/gmx

Bản demo: https://regex101.com/r/IB7j48/2

Lý do của điều này là để tránh lặp lại (25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)mô hình bốn lần. Các giải pháp khác như giải pháp dưới đây hoạt động tốt, nhưng nó không nắm bắt được từng nhóm vì nhiều người yêu cầu.

/^((\d+?)(\.|$)){4}/ 

Cách khác duy nhất để có 4 nhóm chụp là lặp lại mẫu bốn lần:

/^(?<one>\d+)\.(?<two>\d+)\.(?<three>\d+)\.(?<four>\d+)$/

Chụp ipv4 trong perl do đó rất dễ dàng

$ echo "Hey this is my IP address 138.131.254.8, bye!" | \
  perl -ne 'print "[$1, $2, $3, $4]" if \
    /\b((?&byte))\.((?&byte))\.((?&byte))\.((?&byte))
     (?(DEFINE)
        \b(?<byte>25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))
    /x'

[138, 131, 254, 8]

0

IPv4 regexp chính xác, đơn giản và nhỏ gọn nhất mà tôi có thể tưởng tượng là

^(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$

Nhưng những gì về hiệu suất / hiệu quả của ... Xin lỗi, tôi không biết, ai quan tâm?


0

Thử đi:

\b(([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-5][0-5])\.([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-5][0-5])\.([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-5][0-5])\.(2[0-5][0-5]|1[0-9][0-9]|[1-9][0-9]|[1-9]))\b

0
ip address can be from 0.0.0.0 to 255.255.255.255

(((0|1)?[0-9][0-9]?|2[0-4][0-9]|25[0-5])[.]){3}((0|1)?[0-9][0-9]?|2[0-4][0-9]|25[0-5])$

(0|1)?[0-9][0-9]? - checking value from 0 to 199
2[0-4][0-9]- checking value from 200 to 249
25[0-5]- checking value from 250 to 255
[.] --> represent verify . character 
{3} --> will match exactly 3
$ --> end of string

0

Sau đây là biểu thức regex để xác thực Địa chỉ IP.

^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.