Ekspresi reguler yang cocok dengan alamat IPv6 yang valid

111

Saya mengalami masalah saat menulis ekspresi reguler yang cocok dengan alamat IPv6 yang valid, termasuk yang dalam bentuk terkompresi (dengan ::atau nol di depan dihilangkan dari setiap pasangan byte).

Bisakah seseorang menyarankan ekspresi reguler yang akan memenuhi persyaratan?

Saya sedang mempertimbangkan untuk memperluas setiap pasangan byte dan mencocokkan hasilnya dengan ekspresi reguler yang lebih sederhana.

Hanya baca
sumber
1
Lihat intermapper.com/ipv6validator .. ini tertaut ke skrip uji perl
Mottie
Saya telah mencoba semua jawaban di bawah dan jawaban tersebut tidak berfungsi untuk semua kasus pengujian saya dan / atau mereka juga menyertakan IPv4 yang tidak diminta. Saya telah menemukan ini sebagai solusi terbersih sejauh ini: stackoverflow.com/a/21944928/3112803
gfrobenius

Jawaban:

252

Saya tidak bisa mendapatkan jawaban @Factor Mystic untuk berfungsi dengan ekspresi reguler POSIX, jadi saya menulis jawaban yang berfungsi dengan ekspresi reguler POSIX dan ekspresi reguler PERL.

Ini harus cocok:

Ekspresi Reguler IPv6:

(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))

Untuk kemudahan membaca, berikut ini adalah persamaan reguler di atas yang dipisahkan pada titik-titik OR utama menjadi baris-baris terpisah:

# IPv6 RegEx
(
([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|          # 1:2:3:4:5:6:7:8
([0-9a-fA-F]{1,4}:){1,7}:|                         # 1::                              1:2:3:4:5:6:7::
([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|         # 1::8             1:2:3:4:5:6::8  1:2:3:4:5:6::8
([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|  # 1::7:8           1:2:3:4:5::7:8  1:2:3:4:5::8
([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|  # 1::6:7:8         1:2:3:4::6:7:8  1:2:3:4::8
([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|  # 1::5:6:7:8       1:2:3::5:6:7:8  1:2:3::8
([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|  # 1::4:5:6:7:8     1:2::4:5:6:7:8  1:2::8
[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|       # 1::3:4:5:6:7:8   1::3:4:5:6:7:8  1::8  
:((:[0-9a-fA-F]{1,4}){1,7}|:)|                     # ::2:3:4:5:6:7:8  ::2:3:4:5:6:7:8 ::8       ::     
fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|     # fe80::7:8%eth0   fe80::7:8%1     (link-local IPv6 addresses with zone index)
::(ffff(:0{1,4}){0,1}:){0,1}
((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}
(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|          # ::255.255.255.255   ::ffff:255.255.255.255  ::ffff:0:255.255.255.255  (IPv4-mapped IPv6 addresses and IPv4-translated addresses)
([0-9a-fA-F]{1,4}:){1,4}:
((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}
(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])           # 2001:db8:3:4::192.0.2.33  64:ff9b::192.0.2.33 (IPv4-Embedded IPv6 Address)
)

# IPv4 RegEx
((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])

Untuk mempermudah pemahaman di atas, kode "semu" berikut mereplikasi yang di atas:

IPV4SEG  = (25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])
IPV4ADDR = (IPV4SEG\.){3,3}IPV4SEG
IPV6SEG  = [0-9a-fA-F]{1,4}
IPV6ADDR = (
           (IPV6SEG:){7,7}IPV6SEG|                # 1:2:3:4:5:6:7:8
           (IPV6SEG:){1,7}:|                      # 1::                                 1:2:3:4:5:6:7::
           (IPV6SEG:){1,6}:IPV6SEG|               # 1::8               1:2:3:4:5:6::8   1:2:3:4:5:6::8
           (IPV6SEG:){1,5}(:IPV6SEG){1,2}|        # 1::7:8             1:2:3:4:5::7:8   1:2:3:4:5::8
           (IPV6SEG:){1,4}(:IPV6SEG){1,3}|        # 1::6:7:8           1:2:3:4::6:7:8   1:2:3:4::8
           (IPV6SEG:){1,3}(:IPV6SEG){1,4}|        # 1::5:6:7:8         1:2:3::5:6:7:8   1:2:3::8
           (IPV6SEG:){1,2}(:IPV6SEG){1,5}|        # 1::4:5:6:7:8       1:2::4:5:6:7:8   1:2::8
           IPV6SEG:((:IPV6SEG){1,6})|             # 1::3:4:5:6:7:8     1::3:4:5:6:7:8   1::8
           :((:IPV6SEG){1,7}|:)|                  # ::2:3:4:5:6:7:8    ::2:3:4:5:6:7:8  ::8       ::       
           fe80:(:IPV6SEG){0,4}%[0-9a-zA-Z]{1,}|  # fe80::7:8%eth0     fe80::7:8%1  (link-local IPv6 addresses with zone index)
           ::(ffff(:0{1,4}){0,1}:){0,1}IPV4ADDR|  # ::255.255.255.255  ::ffff:255.255.255.255  ::ffff:0:255.255.255.255 (IPv4-mapped IPv6 addresses and IPv4-translated addresses)
           (IPV6SEG:){1,4}:IPV4ADDR               # 2001:db8:3:4::192.0.2.33  64:ff9b::192.0.2.33 (IPv4-Embedded IPv6 Address)
           )

Saya memposting skrip di GitHub yang menguji ekspresi reguler: https://gist.github.com/syzdek/6086792

David M. Syzdek
sumber
3
Anda IPv4 regex tidak cocok dengan IP seperti127.000.000.001
Kentzo
21
Segmen IPv4 tidak boleh menyertakan angka nol di depan. Jika ada nol di depan, segmen IPv4 harus ditafsirkan dalam oktal. Jadi IPV4SEG di atas benar karena tidak mengizinkan '000'. Namun itu mengizinkan '00' yang seharusnya tidak.
par
3
Tidak bekerja untuk saya di browser seperti yang saya harapkan. Genap reg.test yang telah divalidasi ('3zzzzffe: 1900: 4545: 3: 200: f8ff: fe21: 67cf') yang jelas bukan alamat IPv6 yang valid. Memiliki hasil yang jauh lebih baik dengan regex di sini: nbviewer.ipython.org/github/rasbt/python_reference/blob/master/…
Capaj
7
regex ipv6 yang fantastis. menemukan bug kecil dengan bagian tautan lokal. Anda memiliki fe80tempat yang seharusnya seperti itu [fF][eE]80dan ffffyang seharusnya seperti[fF]{4}
pengguna2831628
4
1 untuk menunjukkan bahwa regex dapat (dengan cara yang sama seperti kode sumber apa pun) benar-benar dapat dibaca jika Anda berhati-hati dan memformatnya.
Natix
52

Berikut ini akan memvalidasi alamat IPv4, IPv6 (penuh dan terkompresi), dan IPv6v4 (lengkap dan terkompresi):

'/^(?>(?>([a-f0-9]{1,4})(?>:(?1)){7}|(?!(?:.*[a-f0-9](?>:|$)){8,})((?1)(?>:(?1)){0,6})?::(?2)?)|(?>(?>(?1)(?>:(?1)){5}:|(?!(?:.*[a-f0-9]:){6,})(?3)?::(?>((?1)(?>:(?1)){0,4}):)?)?(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?>\.(?4)){3}))$/iD'
MichaelRushton
sumber
8
Meskipun memvalidasi ip-s dapat dilakukan seperti yang disarankan Frank Krueger, solusi ini adalah solusi yang benar-benar menjawab pertanyaan (meskipun saya belum sepenuhnya mengujinya) serta jika Anda memiliki banyak IP yang ingin Anda uji secara sintaksis dan mungkin cocok untuk sebaris teks, Anda tidak dapat menggunakan teknik validasi IP.
Gyuri
Hai, saya menguji RegExp ini dan tidak berhasil untuk saya. Ia mengatakan D adalah bendera tidak valid dan ketika saya menghapusnya dikatakan "SyntaxError: pembilang tidak valid"
diosney
3
JavaScript mengimplementasikan subset ekspresi reguler gaya Perl, bukan keseluruhan PCRE. Regex saya tidak akan berfungsi tanpa beberapa fitur lanjutan PCRE.
MichaelRushton
2
Ini memberikan pengecualian bagi saya di C #
sarat
1
Kasus uji yang gagal: FE80: 0000: 0000: 0000: 0202: B3FF: FE1E: 8329 Menggunakan versi terbaru Elixir pada tanggal ini, yang menggunakan PCRE di bawahnya.
pmarreck
23

Sepertinya Anda mungkin menggunakan Python. Jika demikian, Anda dapat menggunakan sesuatu seperti ini:

import socket

def check_ipv6(n):
    try:
        socket.inet_pton(socket.AF_INET6, n)
        return True
    except socket.error:
        return False

print check_ipv6('::1') # True
print check_ipv6('foo') # False
print check_ipv6(5)     # TypeError exception
print check_ipv6(None)  # TypeError exception

Saya tidak berpikir Anda harus memiliki IPv6 yang dikompilasi ke Python untuk mendapatkannya inet_pton, yang juga dapat mengurai alamat IPv4 jika Anda masuk socket.AF_INETsebagai parameter pertama. Catatan: ini mungkin tidak berfungsi pada sistem non-Unix.

Joe Hildebrand
sumber
4
Anda harus menentukan jenis pengecualian dalam exceptklausa. Jika tidak, exceptakan menangkap semuanya dan mungkin menutupi kesalahan yang tidak terkait. Tipe di sini seharusnya socket.error.
Ayman Hourieh
A) inet_pton tidak menampilkan pengecualian lain, kecuali jika dokumen salah, dan B) meskipun demikian, apa lagi yang akan Anda kembalikan selain False?
Joe Hildebrand
2
Re: kesalahan lainnya ... jika pengguna mengirimkan non-string, TypeError dimakan. Jelas sebuah daftar bukanlah ipv6, tapi saya mungkin ingin memilikinya karper yang saya berikan dengan jenis yang salah.
Gregg Lind
1
+1 Ini sangat membantu saya. Beberapa poin tambahan yang harus ditambahkan: 1) socket.inet_pton dapat digunakan untuk menguji validitas kedua kelompok alamat IP (IP dan IPv6). 2) Dokumen di sini ( docs.python.org/2/library/socket.html ) menyarankan bahwa ini tersedia di platform Unix. Ini mungkin tidak tersedia di platform Win.
mkoistinen
menggunakan django dan ini membantu!
elad silver
23

Dari " IPv6 regex ":

(\A([0-9a-f]{1,4}:){1,1}(:[0-9a-f]{1,4}){1,6}\Z)|
(\A([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,5}\Z)|
(\A([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,4}\Z)|
(\A([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,3}\Z)|
(\A([0-9a-f]{1,4}:){1,5}(:[0-9a-f]{1,4}){1,2}\Z)|
(\A([0-9a-f]{1,4}:){1,6}(:[0-9a-f]{1,4}){1,1}\Z)|
(\A(([0-9a-f]{1,4}:){1,7}|:):\Z)|
(\A:(:[0-9a-f]{1,4}){1,7}\Z)|
(\A((([0-9a-f]{1,4}:){6})(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})\Z)|
(\A(([0-9a-f]{1,4}:){5}[0-9a-f]{1,4}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})\Z)|
(\A([0-9a-f]{1,4}:){5}:[0-9a-f]{1,4}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|
(\A([0-9a-f]{1,4}:){1,1}(:[0-9a-f]{1,4}){1,4}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|
(\A([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,3}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|
(\A([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,2}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|
(\A([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,1}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|
(\A(([0-9a-f]{1,4}:){1,5}|:):(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|
(\A:(:[0-9a-f]{1,4}){1,5}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)
Factor Mystic
sumber
45
Ekspresi reguler seperti ini harus menjadi "code bau" yang mungkin bukan merupakan solusi yang paling cocok di sini. (Meskipun, saya kira op memang memintanya ...)
Thanatos
10
@ user712092 - setiap orang yang telah melihat basis kode dengan
gangguan pemandangan
2
Ini adalah parodi yang sama sekali tidak perlu untuk RE. Program yang menghasilkannya tidak memahami apa yang dilakukannya. Manusia tidak akan pernah melakukannya dengan cara ini. Jangan tertipu oleh kerumitan yang tampak - RE memang "sihir hitam" bagi banyak orang, tetapi tidak ada alasan untuk menempatkannya di planet lain!
Chuck Kollars
+1 tetapi OMG harus ada cara yang lebih baik untuk melakukan ini: P Untuk referensi: untuk Rails ini mungkin membantu: stackoverflow.com/questions/16965697/…
Tilo
1
Ini memang bau kode; namun setelah melihat, Anda akan melihat bahwa setiap ekspresi reguler cukup ringkas. Masalahnya adalah bahwa ada pola berbeda yang dibuat oleh 'kompresi' ipv6 - Titik dua mulai, tengah, dan akhir, di atas jika Anda telah menggunakan titik dua ganda, Anda tidak dapat menggunakannya lagi, di atas total titik dua sebelum dan setelah tanda ganda harus dijumlahkan. Perl 6 mungkin bisa mengatasi ini, tetapi ini jauh melampaui sintaks PCRE. (PS - Saya tidak menghitung ipv4 yang disematkan di akhir, yang lebih panjang dari bagian ipv6!)
Gerard ONeill
11

Saya harus mendukung jawaban dari Frank Krueger .

Sementara Anda mengatakan Anda memerlukan ekspresi reguler untuk mencocokkan alamat IPv6, saya berasumsi apa yang sebenarnya Anda butuhkan adalah dapat memeriksa apakah string yang diberikan adalah alamat IPv6 yang valid. Ada perbedaan yang halus namun penting di sini.

Ada lebih dari satu cara untuk memeriksa apakah string yang diberikan adalah alamat IPv6 yang valid dan pencocokan ekspresi reguler hanyalah satu solusi.

Gunakan perpustakaan yang ada jika Anda bisa. Perpustakaan akan memiliki lebih sedikit bug dan penggunaannya akan menghasilkan lebih sedikit kode untuk Anda pelihara.

Ekspresi reguler yang disarankan oleh Factor Mystic panjang dan rumit. Kemungkinan besar berhasil, tetapi Anda juga harus mempertimbangkan bagaimana Anda akan mengatasinya jika tiba-tiba gagal. Poin yang ingin saya sampaikan di sini adalah jika Anda tidak dapat membentuk ekspresi reguler yang diperlukan sendiri, Anda tidak akan dapat dengan mudah men-debugnya.

Jika Anda tidak memiliki pustaka yang sesuai, mungkin lebih baik menulis rutin validasi IPv6 Anda sendiri yang tidak bergantung pada ekspresi reguler. Jika Anda menulisnya Anda memahaminya dan jika Anda memahaminya Anda dapat menambahkan komentar untuk menjelaskannya sehingga orang lain juga dapat memahami dan selanjutnya memeliharanya.

Bertindak dengan hati-hati saat menggunakan ekspresi reguler yang fungsinya tidak dapat Anda jelaskan kepada orang lain.

Jon Cram
sumber
1
Menggunakan dua ekspresi reguler, ekspresi liberal dan ekspresi pengecualian untuk menjebak alamat tidak valid yang diizinkan oleh yang pertama, mungkin lebih mudah daripada satu ekspresi ( return ex1.match(S) && ! ex2.match(S)).
Raedwald
4
Anda berasumsi bahwa dia memvalidasi IP individu ketika dia hampir pasti mencari IP dalam blok teks yang besar.
Navin
8

Saya bukan ahli Ipv6 tetapi saya pikir Anda bisa mendapatkan hasil yang cukup bagus dengan lebih mudah dengan yang ini:

^([0-9A-Fa-f]{0,4}:){2,7}([0-9A-Fa-f]{1,4}$|((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4})$

untuk menjawab "adalah ipv6 yang valid" sepertinya oke bagi saya. Untuk memecahnya menjadi beberapa bagian ... lupakan saja. Saya telah menghilangkan satu yang tidak ditentukan (: :) karena tidak ada gunanya memiliki "alamat yang tidak ditentukan" dalam database saya.

permulaan: ^([0-9A-Fa-f]{0,4}:){2,7}<- cocokkan bagian yang dapat dikompresi, kita dapat menerjemahkan ini sebagai: antara 2 dan 7 titik dua yang mungkin memiliki angka heaxadecimal di antara keduanya.

diikuti oleh: [0-9A-Fa-f]{1,4}$<- angka heksadesimal (di depan 0 dihilangkan) ATAU ((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}<- alamat Ipv4

Remi Morin
sumber
1
1 untuk benar-benar berpegang pada pertanyaan OP dan menghadirkan regex yang relatif tampan yang agak berfungsi.
xebeche
1
Ini tidak cocok dengan ":: 1"
lsalamon
Hah? Dalam sintaks regex java itu cocok:start() = 0, end() = 3 group(0) = "::1" group(1) = ":" group(2) = "1" group(3) = "null" group(4) = "null" group(5) = "null"
Remi Morin
Di tempat lain, seseorang memberi tahu saya tentang masalah dengan regex saya, bagian "::" yang dikompresi hanya dapat muncul sekali. Jadi ":: 1 :: 2" akan cocok dengan regex saya tetapi ini bukan IPV6 yang valid. Regex kedua dapat memvalidasi kasus ini. Rekomendasi lengkapnya adalah menggunakan stateful parser untuk memvalidasi. Saya setuju bahwa kode yang dihasilkan akan lebih mudah dibaca dan dipelihara (dan seseorang mungkin sudah mengkodekannya dalam open source di suatu tempat).
Remi Morin
8

Ini menangkap loopback (:: 1) juga dan alamat ipv6. diubah {} menjadi + dan meletakkan: di dalam kurung siku pertama.

([a-f0-9:]+:+)+[a-f0-9]+

diuji dengan ifconfig -a output http://regexr.com/

Unix atau Mac OSx terminal o opsi mengembalikan hanya keluaran yang cocok (ipv6) termasuk: 1

ifconfig -a | egrep -o '([a-f0-9:]+:+)+[a-f0-9]+'

Dapatkan Semua alamat IP (IPv4 ATAU IPv6) dan cetak cocok pada istilah OSx unix

ifconfig -a | egrep -o '([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}) | (([a-f0-9:]+:+)+[a-f0-9]+)'
Rohit Malgaonkar
sumber
Saya suka kesederhanaan. Ini akhirnya berhasil bagi saya:ip a | grep -Po '[\w:]+:+[\w:]+'
Noam Manos
Humor dihargai!
Soumya Kanti
Ketika saya menjalankan ipconfig / all, alamat ip saya diakhiri dengan% 10, ekspresi ini tidak cocok dengan bagian ini?
Peter
7

Ekspresi reguler ini akan cocok dengan alamat IPv6 dan IPv4 yang valid sesuai dengan implementasi GNU C ++ dari regex dengan mode REGULAR EXTENDED yang digunakan:

"^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:)))(%.+)?\s*$"
janCoffee
sumber
5

Awas! Di Java, penggunaan InetAddress dan kelas terkait (Inet4Address, Inet6Address, URL) mungkin melibatkan lalu lintas jaringan! Misalnya penyelesaian DNS (URL.equals, InetAddress dari string!). Panggilan ini mungkin memakan waktu lama dan memblokir!

Untuk IPv6 saya punya sesuatu seperti ini. Ini tentu saja tidak menangani detail yang sangat halus dari IPv6 seperti indeks zona yang hanya diperbolehkan pada beberapa kelas alamat IPv6. Dan regex ini tidak ditulis untuk pengambilan grup, ini hanya jenis regexp yang "cocok".

S - Segmen IPv6 = [0-9a-f]{1,4}

I - IPv4 = (?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9]{1,2})\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9]{1,2})

Skema (bagian pertama cocok dengan alamat IPv6 dengan akhiran IPv4, bagian kedua cocok dengan alamat IPv6, bagian terakhir indeks zona):

(
(
::(S:){0,5}|
S::(S:){0,4}|
(S:){2}:(S:){0,3}|
(S:){3}:(S:){0,2}|
(S:){4}:(S:)?|
(S:){5}:|
(S:){6}
)
I

|

:(:|(:S){1,7})|
S:(:|(:S){1,6})|
(S:){2}(:|(:S){1,5})|
(S:){3}(:|(:S){1,4})|
(S:){4}(:|(:S){1,3})|
(S:){5}(:|(:S){1,2})|
(S:){6}(:|(:S))|
(S:){7}:|
(S:){7}S
)

(?:%[0-9a-z]+)?

Dan di sini might regex (case insensitive, dikelilingi dengan apa yang pernah dibutuhkan seperti awal / akhir baris, dll.):

(?:
(?:
::(?:[0-9a-f]{1,4}:){0,5}|
[0-9a-f]{1,4}::(?:[0-9a-f]{1,4}:){0,4}|
(?:[0-9a-f]{1,4}:){2}:(?:[0-9a-f]{1,4}:){0,3}|
(?:[0-9a-f]{1,4}:){3}:(?:[0-9a-f]{1,4}:){0,2}|
(?:[0-9a-f]{1,4}:){4}:(?:[0-9a-f]{1,4}:)?|
(?:[0-9a-f]{1,4}:){5}:|
(?:[0-9a-f]{1,4}:){6}
)
(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9]{1,2})\.){3}
(?:25[0-5]|2[0-4][0-9]|[01]?[0-9]{1,2})|

:(?::|(?::[0-9a-f]{1,4}){1,7})|
[0-9a-f]{1,4}:(?::|(?::[0-9a-f]{1,4}){1,6})|
(?:[0-9a-f]{1,4}:){2}(?::|(?::[0-9a-f]{1,4}){1,5})|
(?:[0-9a-f]{1,4}:){3}(?::|(?::[0-9a-f]{1,4}){1,4})|
(?:[0-9a-f]{1,4}:){4}(?::|(?::[0-9a-f]{1,4}){1,3})|
(?:[0-9a-f]{1,4}:){5}(?::|(?::[0-9a-f]{1,4}){1,2})|
(?:[0-9a-f]{1,4}:){6}(?::|(?::[0-9a-f]{1,4}))|
(?:[0-9a-f]{1,4}:){7}:|
(?:[0-9a-f]{1,4}:){7}[0-9a-f]{1,4}
)

(?:%[0-9a-z]+)?
pengguna2623580
sumber
4

Regex berikut hanya untuk IPv6. Grup 1 cocok dengan IP.

(([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4})
Jitendra Gosavi
sumber
+1 Tidak selalu perlu memiliki ekspresi reguler super kompleks yang tidak dapat dipahami manusia. Saya akan menggunakan yang ini karena saya mengerti apa fungsinya dan dalam kasus saya, saya dapat yakin bahwa jika saya mendapatkan sesuatu yang menyerupai ipv6 yang valid, jadi itu adalah ipv6 yang valid.
David L.
3
ini tidak cocok, katakanlah: fe80 :: 1 atau 2342: 32fd :: 2d32
James
3

Regex sederhana yang akan cocok, tetapi saya tidak akan merekomendasikan untuk validasi dalam bentuk apa pun adalah ini:

([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}

Perhatikan bahwa ini cocok dengan kompresi di manapun dalam alamat, meskipun tidak akan cocok dengan alamat loopback :: 1. Saya menemukan ini sebagai kompromi yang masuk akal untuk menjaga ekspresi reguler tetap sederhana.

Saya berhasil menggunakan ini dalam aturan pemilihan cerdas iTerm2 ke alamat IPv6 empat kali klik.

JinnKo
sumber
3
Maksudmu A-F, tidak A-Z! Perhatikan juga bahwa Anda tidak termasuk notasi titik-titik.
xebeche
3

Jika Anda menggunakan Perl coba Net :: IPv6Addr

use Net::IPv6Addr;

if( defined Net::IPv6Addr::is_ipv6($ip_address) ){
  print "Looks like an ipv6 address\n";
}

NetAddr :: IP

use NetAddr::IP;

my $obj = NetAddr::IP->new6($ip_address);

Validasi :: IP

use Validate::IP qw'is_ipv6';

if( is_ipv6($ip_address) ){
  print "Looks like an ipv6 address\n";
}
Brad Gilbert
sumber
2

Di Scala, gunakan validator Apache Commons yang terkenal.

http://mvnrepository.com/artifact/commons-validator/commons-validator/1.4.1

libraryDependencies += "commons-validator" % "commons-validator" % "1.4.1"


import org.apache.commons.validator.routines._

/**
 * Validates if the passed ip is a valid IPv4 or IPv6 address.
 *
 * @param ip The IP address to validate.
 * @return True if the passed IP address is valid, false otherwise.
 */  
 def ip(ip: String) = InetAddressValidator.getInstance().isValid(ip)

Mengikuti tes metode ip(ip: String):

"The `ip` validator" should {
  "return false if the IPv4 is invalid" in {
    ip("123") must beFalse
    ip("255.255.255.256") must beFalse
    ip("127.1") must beFalse
    ip("30.168.1.255.1") must beFalse
    ip("-1.2.3.4") must beFalse
  }

  "return true if the IPv4 is valid" in {
    ip("255.255.255.255") must beTrue
    ip("127.0.0.1") must beTrue
    ip("0.0.0.0") must beTrue
  }

  //IPv6
  //@see: http://www.ronnutter.com/ipv6-cheatsheet-on-identifying-valid-ipv6-addresses/
  "return false if the IPv6 is invalid" in {
    ip("1200::AB00:1234::2552:7777:1313") must beFalse
  }

  "return true if the IPv6 is valid" in {
    ip("1200:0000:AB00:1234:0000:2552:7777:1313") must beTrue
    ip("21DA:D3:0:2F3B:2AA:FF:FE28:9C5A") must beTrue
  }
}
OliverKK
sumber
Menarik, Ia mengklaim untuk memeriksa bahwa itu adalah alamat yang valid, " Memvalidasi jika ip yang dilewati adalah alamat IPv4 atau IPv6 yang valid. ", Tetapi itu benar-benar hanya memeriksa bahwa itu diformat sebagai alamat yang valid. Misalnya, 1200:0000:AB00:1234:0000:2552:7777:1313adalah format yang valid untuk alamat IPv6, tetapi ini bukan alamat IPv6 yang valid saat metode pengujian kembali. Saya berani bertaruh menurutnya itu 241.54.113.65adalah alamat IPv4 yang valid.
Ron Maupin
2

Melihat pola yang termasuk dalam jawaban lain ada sejumlah pola bagus yang dapat diperbaiki dengan mereferensikan kelompok dan memanfaatkan lookahead. Berikut adalah contoh pola yang merujuk pada diri sendiri yang akan saya gunakan di PHP jika saya harus:

^(?<hgroup>(?<hex>[[:xdigit:]]{0,4}) # grab a sequence of up to 4 hex digits
                                     # and name this pattern for usage later
     (?<!:::):{1,2})                 # match 1 or 2 ':' characters
                                     # as long as we can't match 3
 (?&hgroup){1,6} # match our hex group 1 to 6 more times
 (?:(?:
    # match an ipv4 address or
    (?<dgroup>2[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3}(?&dgroup)
    # match our hex group one last time
    |(?&hex))$

Catatan: PHP memiliki filter bawaan untuk ini yang akan menjadi solusi yang lebih baik daripada pola ini.

Analisis Regex101

Steve Buzonas
sumber
2

Saya membuat yang berikut ini menggunakan python dan bekerja dengan modul re. Pernyataan di depan memastikan bahwa jumlah titik atau titik dua yang benar muncul di alamat. Itu tidak mendukung IPv4 dalam notasi IPv6.

pattern = '^(?=\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$)(?:(?:25[0-5]|[12][0-4][0-9]|1[5-9][0-9]|[1-9]?[0-9])\.?){4}$|(?=^(?:[0-9a-f]{0,4}:){2,7}[0-9a-f]{0,4}$)(?![^:]*::.+::[^:]*$)(?:(?=.*::.*)|(?=\w+:\w+:\w+:\w+:\w+:\w+:\w+:\w+))(?:(?:^|:)(?:[0-9a-f]{4}|[1-9a-f][0-9a-f]{0,3})){0,8}(?:::(?:[0-9a-f]{1,4}(?:$|:)){0,6})?$'
result = re.match(pattern, ip)
if result: result.group(0)
Mike Wilmes
sumber
2

Regex untuk ipv6 bisa menjadi sangat rumit ketika Anda mempertimbangkan alamat dengan ipv4 tertanam dan alamat yang dikompresi, seperti yang Anda lihat dari beberapa jawaban ini.

Pustaka Java IPAddress sumber terbuka akan memvalidasi semua representasi standar IPv6 dan IPv4 dan juga mendukung panjang prefiks (dan validasinya). Penafian: Saya adalah manajer proyek perpustakaan itu.

Contoh kode:

        try {
            IPAddressString str = new IPAddressString("::1");
            IPAddress addr = str.toAddress();
            if(addr.isIPv6() || addr.isIPv6Convertible()) {
                IPv6Address ipv6Addr = addr.toIPv6();
            }
            //use address
        } catch(AddressStringException e) {
            //e.getMessage has validation error
        }
Sean F
sumber
1

Di Java, Anda dapat menggunakan kelas perpustakaan sun.net.util.IPAddressUtil:

IPAddressUtil.isIPv6LiteralAddress(iPaddress);
pengguna463639
sumber
3
sun.net. * adalah API pribadi.
David Kocher
1

Sulit untuk menemukan ekspresi reguler yang berfungsi untuk semua kasus IPv6. Mereka biasanya sulit dirawat, tidak mudah dibaca dan dapat menyebabkan masalah kinerja. Oleh karena itu, saya ingin membagikan solusi alternatif yang telah saya kembangkan: Regular Expression (RegEx) for IPv6 Separate from IPv4

Sekarang Anda mungkin bertanya bahwa "Metode ini hanya menemukan IPv6, bagaimana saya dapat menemukan IPv6 dalam teks atau file?" Berikut adalah metode untuk masalah ini juga.

Catatan : Jika Anda tidak ingin menggunakan kelas IPAddress di .NET, Anda juga dapat menggantinya dengan metode saya . Ini juga mencakup IPv4 yang dipetakan dan kasus khusus juga, sedangkan IPAddress tidak mencakup.

class IPv6
{
    public List<string> FindIPv6InFile(string filePath)
    {
        Char ch;
        StringBuilder sbIPv6 = new StringBuilder();
        List<string> listIPv6 = new List<string>();
        StreamReader reader = new StreamReader(filePath);
        do
        {
            bool hasColon = false;
            int length = 0;

            do
            {
                ch = (char)reader.Read();

                if (IsEscapeChar(ch))
                    break;

                //Check the first 5 chars, if it has colon, then continue appending to stringbuilder
                if (!hasColon && length < 5)
                {
                    if (ch == ':')
                    {
                        hasColon = true;
                    }
                    sbIPv6.Append(ch.ToString());
                }
                else if (hasColon) //if no colon in first 5 chars, then dont append to stringbuilder
                {
                    sbIPv6.Append(ch.ToString());
                }

                length++;

            } while (!reader.EndOfStream);

            if (hasColon && !listIPv6.Contains(sbIPv6.ToString()) && IsIPv6(sbIPv6.ToString()))
            {
                listIPv6.Add(sbIPv6.ToString());
            }

            sbIPv6.Clear();

        } while (!reader.EndOfStream);
        reader.Close();
        reader.Dispose();

        return listIPv6;
    }

    public List<string> FindIPv6InText(string text)
    {
        StringBuilder sbIPv6 = new StringBuilder();
        List<string> listIPv6 = new List<string>();

        for (int i = 0; i < text.Length; i++)
        {
            bool hasColon = false;
            int length = 0;

            do
            {
                if (IsEscapeChar(text[length + i]))
                    break;

                //Check the first 5 chars, if it has colon, then continue appending to stringbuilder
                if (!hasColon && length < 5)
                {
                    if (text[length + i] == ':')
                    {
                        hasColon = true;
                    }
                    sbIPv6.Append(text[length + i].ToString());
                }
                else if (hasColon) //if no colon in first 5 chars, then dont append to stringbuilder
                {
                    sbIPv6.Append(text[length + i].ToString());
                }

                length++;

            } while (i + length != text.Length);

            if (hasColon && !listIPv6.Contains(sbIPv6.ToString()) && IsIPv6(sbIPv6.ToString()))
            {
                listIPv6.Add(sbIPv6.ToString());
            }

            i += length;
            sbIPv6.Clear();
        }

        return listIPv6;
    }

    bool IsEscapeChar(char ch)
    {
        if (ch != ' ' && ch != '\r' && ch != '\n' && ch!='\t')
        {
            return false;
        }

        return true;
    }

    bool IsIPv6(string maybeIPv6)
    {
        IPAddress ip;
        if (IPAddress.TryParse(maybeIPv6, out ip))
        {
            return ip.AddressFamily == AddressFamily.InterNetworkV6;
        }
        else
        {
            return false;
        }
    }

}
Nuh Metin Güler
sumber
1

InetAddressUtilsmemiliki semua pola yang ditentukan. Saya akhirnya menggunakan pola mereka secara langsung, dan menempelkannya di sini untuk referensi:

private static final String IPV4_BASIC_PATTERN_STRING =
        "(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}" + // initial 3 fields, 0-255 followed by .
         "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])"; // final field, 0-255

private static final Pattern IPV4_PATTERN =
    Pattern.compile("^" + IPV4_BASIC_PATTERN_STRING + "$");

private static final Pattern IPV4_MAPPED_IPV6_PATTERN = // TODO does not allow for redundant leading zeros
        Pattern.compile("^::[fF]{4}:" + IPV4_BASIC_PATTERN_STRING + "$");

private static final Pattern IPV6_STD_PATTERN =
    Pattern.compile(
            "^[0-9a-fA-F]{1,4}(:[0-9a-fA-F]{1,4}){7}$");

private static final Pattern IPV6_HEX_COMPRESSED_PATTERN =
    Pattern.compile(
            "^(([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4}){0,5})?)" + // 0-6 hex fields
             "::" +
             "(([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4}){0,5})?)$"); // 0-6 hex fields 
pengguna4604205
sumber
1

Menggunakan Ruby? Coba ini:

/^(((?=.*(::))(?!.*\3.+\3))\3?|[\dA-F]{1,4}:)([\dA-F]{1,4}(\3|:\b)|\2){5}(([\dA-F]{1,4}(\3|:\b|$)|\2){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4})\z/i
Ahamx
sumber
1

Bergantung pada kebutuhan Anda, perkiraan seperti:

[0-9a-f:]+

mungkin cukup (seperti grep file log sederhana, misalnya.)

Bill Lipa
sumber
0

Untuk pengguna PHP 5.2+ filter_varbekerja dengan baik.

Saya tahu ini tidak menjawab pertanyaan asli (khususnya solusi regex), tetapi saya memposting ini dengan harapan dapat membantu orang lain di masa depan.

$is_ip4address = (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== FALSE);
$is_ip6address = (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== FALSE);
Wireblue
sumber
0

Ini akan berfungsi untuk IPv4 dan IPv6:

^(([0-9a-f]{0,4}:){1,7}[0-9a-f]{1,4}|([0-9]{1,3}\.){3}[0-9]{1,3})$
Chris
sumber
2
Ini cocok dengan alamat yang tidak valid dengan 2 contoh ::. misalnya2404:6800::4003:c02::8a
nhahtdh
cocok dengan IPv4 666.666.666.666 yang tidak valid
Ryan Williams
0

Inilah yang saya dapatkan, menggunakan sedikit lookahead dan grup bernama. Ini tentu saja hanya IPv6, tetapi tidak akan mengganggu pola tambahan jika Anda ingin menambahkan IPv4:

(?=([0-9a-f]+(:[0-9a-f])*)?(?P<wild>::)(?!([0-9a-f]+:)*:))(::)?([0-9a-f]{1,4}:{1,2}){0,6}(?(wild)[0-9a-f]{0,4}|[0-9a-f]{1,4}:[0-9a-f]{1,4})
pengguna1977022
sumber
0

Anda dapat menggunakan alat shell ipextract yang saya buat untuk tujuan ini. Mereka didasarkan pada regexp dan grep.

Pemakaian:

$ ifconfig | ipextract6
fe80::1%lo0
::1
fe80::7ed1:c3ff:feec:dee1%en0
Phil L.
sumber
0

Hanya mencocokkan yang lokal dari asal dengan menyertakan tanda kurung siku. Saya tahu ini tidak komprehensif tetapi dalam javascript yang lain sulit untuk melacak masalah terutama yang tidak berfungsi, jadi ini sepertinya memberi saya apa yang saya butuhkan untuk saat ini. AF kapital tambahan juga tidak diperlukan.

^\[([0-9a-fA-F]{1,4})(\:{1,2})([0-9a-fA-F]{1,4})(\:{1,2})([0-9a-fA-F]{1,4})(\:{1,2})([0-9a-fA-F]{1,4})(\:{1,2})([0-9a-fA-F]{1,4})\]

Versi Jinnko disederhanakan dan lebih baik saya mengerti.

Tuan James
sumber
0

Seperti yang dinyatakan di atas, cara lain untuk mendapatkan representasi tekstual IPv6 yang memvalidasi parser adalah dengan menggunakan pemrograman. Ini adalah salah satu yang sepenuhnya sesuai dengan RFC-4291 dan RFC-5952. Saya telah menulis kode ini di ANSI C (bekerja dengan GCC, lulus tes di Linux - bekerja dengan clang, lulus tes di FreeBSD). Jadi, ini hanya bergantung pada pustaka standar ANSI C, sehingga dapat dikompilasi di mana saja (saya telah menggunakannya untuk penguraian IPv6 di dalam modul kernel dengan FreeBSD).

// IPv6 textual representation validating parser fully compliant with RFC-4291 and RFC-5952
// BSD-licensed / Copyright 2015-2017 Alexandre Fenyo

#include <string.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>

typedef enum { false, true } bool;

static const char hexdigits[] = "0123456789abcdef";
static int digit2int(const char digit) {
  return strchr(hexdigits, digit) - hexdigits;
}

// This IPv6 address parser handles any valid textual representation according to RFC-4291 and RFC-5952.
// Other representations will return -1.
//
// note that str input parameter has been modified when the function call returns
//
// parse_ipv6(char *str, struct in6_addr *retaddr)
// parse textual representation of IPv6 addresses
// str:     input arg
// retaddr: output arg
int parse_ipv6(char *str, struct in6_addr *retaddr) {
  bool compressed_field_found = false;
  unsigned char *_retaddr = (unsigned char *) retaddr;
  char *_str = str;
  char *delim;

  bzero((void *) retaddr, sizeof(struct in6_addr));
  if (!strlen(str) || strchr(str, ':') == NULL || (str[0] == ':' && str[1] != ':') ||
      (strlen(str) >= 2 && str[strlen(str) - 1] == ':' && str[strlen(str) - 2] != ':')) return -1;

  // convert transitional to standard textual representation
  if (strchr(str, '.')) {
    int ipv4bytes[4];
    char *curp = strrchr(str, ':');
    if (curp == NULL) return -1;
    char *_curp = ++curp;
    int i;
    for (i = 0; i < 4; i++) {
      char *nextsep = strchr(_curp, '.');
      if (_curp[0] == '0' || (i < 3 && nextsep == NULL) || (i == 3 && nextsep != NULL)) return -1;
      if (nextsep != NULL) *nextsep = 0;
      int j;
      for (j = 0; j < strlen(_curp); j++) if (_curp[j] < '0' || _curp[j] > '9') return -1;
      if (strlen(_curp) > 3) return -1;
      const long val = strtol(_curp, NULL, 10);
      if (val < 0 || val > 255) return -1;
      ipv4bytes[i] = val;
      _curp = nextsep + 1;
    }
    sprintf(curp, "%x%02x:%x%02x", ipv4bytes[0], ipv4bytes[1], ipv4bytes[2], ipv4bytes[3]);
  }

  // parse standard textual representation
  do {
    if ((delim = strchr(_str, ':')) == _str || (delim == NULL && !strlen(_str))) {
      if (delim == str) _str++;
      else if (delim == NULL) return 0;
      else {
        if (compressed_field_found == true) return -1;
        if (delim == str + strlen(str) - 1 && _retaddr != (unsigned char *) (retaddr + 1)) return 0;
        compressed_field_found = true;
        _str++;
        int cnt = 0;
        char *__str;
        for (__str = _str; *__str; ) if (*(__str++) == ':') cnt++;
        unsigned char *__retaddr = - 2 * ++cnt + (unsigned char *) (retaddr + 1);
        if (__retaddr <= _retaddr) return -1;
        _retaddr = __retaddr;
      }
    } else {
      char hexnum[4] = "0000";
      if (delim == NULL) delim = str + strlen(str);
      if (delim - _str > 4) return -1;
      int i;
      for (i = 0; i < delim - _str; i++)
        if (!isxdigit(_str[i])) return -1;
        else hexnum[4 - (delim - _str) + i] = tolower(_str[i]);
      _str = delim + 1;
      *(_retaddr++) = (digit2int(hexnum[0]) << 4) + digit2int(hexnum[1]);
      *(_retaddr++) = (digit2int(hexnum[2]) << 4) + digit2int(hexnum[3]);
    }
  } while (_str < str + strlen(str));
  return 0;
}
Alexandre Fenyo
sumber
-1

Coba satu baris kecil ini. Ini seharusnya hanya cocok dengan alamat IPv6 tidak terkompresi / terkompresi yang valid (tidak ada hibrida IPv4)

/(?!.*::.*::)(?!.*:::.*)(?!:[a-f0-9])((([a-f0-9]{1,4})?[:](?!:)){7}|(?=(.*:[:a-f0-9]{1,4}::|^([:a-f0-9]{1,4})?::))(([a-f0-9]{1,4})?[:]{1,2}){1,6})[a-f0-9]{1,4}/
Carlos Velazquez
sumber
Sebenarnya, alamat IPv6 yang valid termasuk tidak terkompresi, terkompresi, hibrida tidak terkompresi, dan hibrida terkompresi. Ini benar-benar membutuhkan lebih dari apa yang Anda miliki untuk benar-benar mencocokkan representasi teks yang valid dari sebuah alamat IPv6.
Ron Maupin
-2

Regex memungkinkan penggunaan angka nol di depan di bagian IPv4.

Beberapa distro Unix dan Mac mengubah segmen tersebut menjadi oktal.

Saya sarankan menggunakan 25[0-5]|2[0-4]\d|1\d\d|[1-9]?\dsebagai segmen IPv4.

Aeron
sumber
-2

Jika Anda hanya menginginkan IP normal (tanpa garis miring), di sini:

^(?:[0-9a-f]{1,4}(?:::)?){0,7}::[0-9a-f]+$

Saya menggunakannya untuk penyorot sintaks saya di aplikasi editor file host. Bekerja sebagai pesona.

Harry
sumber
Tidak mungkin cara ini berfungsi dengan baik, tidak dapat mencocokkan satu alamat ipv6 dengan satu titik dua di dalamnya, semua kecocokan Anda menggunakan titik dua ganda, dan Anda secara eksplisit memerlukan titik dua ganda untuk grup terakhir Anda, peringkasan dapat terjadi di mana saja .. .
KillianDS
(?: [0-9a-f] {1,4} (? :::?)?) {0,7} ::? [0-9a-f] {1,4}
Harry
Masih salah, tetapi meskipun demikian Anda akan mengulang jawaban JinnKo, yang cukup baik untuk tujuan sederhana, tetapi masih memiliki kekurangan (tidak menangkap ringkasan ganda dan tidak mengizinkan pangkat empat bertitik, atau localhost, atau :: termination,. ..)
KillianDS