Wyrażenie regularne pasujące do prawidłowych adresów IPv6

111

Mam problem z zapisaniem wyrażenia regularnego pasującego do prawidłowych adresów IPv6, w tym tych w ich skompresowanej formie (z ::pominięciem zer lub zerem na początku w każdej parze bajtów).

Czy ktoś może zasugerować wyrażenie regularne, które spełniłoby to wymaganie?

Rozważam rozszerzenie każdej pary bajtów i dopasowanie wyniku do prostszego wyrażenia regularnego.

Tylko czytać
źródło
1
Sprawdź intermapper.com/ipv6validator .. to prowadzi do tego skryptu testowego Perla
Mottie
Wypróbowałem wszystkie poniższe odpowiedzi i nie działają one dla wszystkich moich przypadków testowych i / lub zawierają również IPv4, o który nie pytano. Uważam, że jest to jak dotąd najczystsze rozwiązanie: stackoverflow.com/a/21944928/3112803
gfrobenius

Odpowiedzi:

252

Nie udało mi się uzyskać odpowiedzi @Factor Mystic na pracę z wyrażeniami regularnymi POSIX, więc napisałem taki, który działa z wyrażeniami regularnymi POSIX i wyrażeniami regularnymi PERL.

Powinien pasować:

Wyrażenie regularne 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]))

Dla ułatwienia czytania, poniższe wyrażenie regularne zostało podzielone w głównych punktach LUB na osobne wiersze:

# 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])

Aby ułatwić zrozumienie powyższego, poniższy „pseudo” kod powiela powyższy:

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)
           )

Opublikowałem skrypt na GitHubie, który testuje wyrażenie regularne: https://gist.github.com/syzdek/6086792

David M. Syzdek
źródło
3
Twoje wyrażenie regularne IPv4 nie pasuje do adresów IP, takich jak127.000.000.001
Kentzo
21
Segmenty IPv4 nie powinny zawierać zer wiodących. Jeśli występuje zero wiodące, segment IPv4 powinien być interpretowany ósemkowo. Tak więc powyższy IPV4SEG jest poprawny, ponieważ nie zezwala na „000”. Dopuszcza jednak „00”, czego nie powinien.
par
3
Nie działało u mnie w przeglądarce, jak bym się spodziewał. Zweryfikowano nawet reg.test ('3zzzzffe: 1900: 4545: 3: 200: f8ff: fe21: 67cf'), który oczywiście nie jest prawidłowym adresem IPv6. Miałem znacznie lepsze wyniki z wyrażeniem regularnym tutaj: nbviewer.ipython.org/github/rasbt/python_reference/blob/master/…
Capaj
7
fantastyczne wyrażenie regularne ipv6. znalazłem mały błąd w sekcji link local. miałeś fe80gdzie powinno być coś takiego, [fF][eE]80a ffffktóre powinno być jakoś[fF]{4}
user2831628
4
+1 za pokazanie, że wyrażenia regularne mogą być (tak samo jak każdy kod źródłowy) faktycznie czytelne, jeśli zachowasz ostrożność i sformatujesz je.
Natix
52

Poniższe czynności sprawdzą poprawność adresów IPv4, IPv6 (pełne i skompresowane) oraz IPv6v4 (pełne i skompresowane):

'/^(?>(?>([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
źródło
8
Mimo że walidację adresów IP można przeprowadzić zgodnie z sugestiami Franka Kruegera, to rozwiązanie jest tym, które faktycznie odpowiada na pytanie (chociaż jeszcze go nie w pełni przetestowałem), a także jeśli masz wiele adresów IP, które chcesz przetestować składniowo i może dopasować w wierszu tekstu, nie możesz użyć techniki sprawdzania poprawności adresu IP.
Gyuri,
Cześć, przetestowałem ten RegExp i nie działał dla mnie. Mówi, że D jest nieprawidłową flagą, a kiedy ją
usuwam,
3
JavaScript implementuje podzbiór wyrażeń regularnych w stylu Perla, a nie całość PCRE. Moje wyrażenie regularne nie będzie działać bez niektórych zaawansowanych funkcji PCRE.
MichaelRushton
2
To daje mi wyjątek w C #
sarat,
1
Przypadek testowy zakończony niepowodzeniem: FE80: 0000: 0000: 0000: 0202: B3FF: FE1E: 8329 Korzystanie z najnowszej wersji Elixiru w tym dniu, która używa PCRE pod spodem.
pmarreck
23

Wygląda na to, że używasz Pythona. Jeśli tak, możesz użyć czegoś takiego:

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

Nie sądzę, abyś musiał mieć wkompilowany IPv6 do Pythona, aby uzyskać inet_pton, który może również analizować adresy IPv4, jeśli podasz socket.AF_INETjako pierwszy parametr. Uwaga: to może nie działać na systemach innych niż Unix.

Joe Hildebrand
źródło
4
W exceptklauzuli należy określić typ wyjątku . W przeciwnym razie exceptprzechwyci wszystko i może maskować niepowiązane błędy. Powinien to być typ socket.error.
Ayman Hourieh
A) inet_pton nie zgłasza innych wyjątków, chyba że dokumenty są błędne, i B) nawet gdyby tak było, co jeszcze byś zwrócił oprócz Fałsz?
Joe Hildebrand
2
Re: inne błędy ... jeśli użytkownik przekaże nie-string, TypeError zostanie zjedzony. Najwyraźniej lista nie jest IPv6, ale prawdopodobnie chciałbym, żeby okazało się, że podałem niewłaściwy typ.
Gregg Lind
1
+1 To mi bardzo pomogło. Kilka dodatkowych punktów, które należy dodać: 1) socket.inet_pton może być użyty do sprawdzenia poprawności obu rodzin adresów IP (IP i IPv6). 2) Dokumentacja tutaj ( docs.python.org/2/library/socket.html ) sugeruje, że jest to dostępne na platformach Unix. Może nie być dostępny na platformach Win.
mkoistinen
używając django i to pomaga!
elad silver
23

Z „ 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
źródło
45
Wyrażenie regularne takie jak to powinno być „zapachem kodu”, który być może nie jest tutaj najlepszym rozwiązaniem. (Chociaż wydaje mi się, że operacja o to poprosiła ...)
Thanatos
10
@ user712092 - każdy, kto widział bazę kodu z takimi
oczami
2
To zupełnie niepotrzebna parodia dla RE. Program, który go wygenerował, nie rozumiał, co robi. Człowiek nigdy nie zrobiłby tego w ten sposób. Nie daj się zwieść pozornej złożoności - RE są rzeczywiście „czarną magią” dla wielu ludzi, ale nie ma powodu, aby umieszczać je na innej planecie!
Chuck Kollars,
+1, ale OMG, musi być lepszy sposób na zrobienie tego: P Dla odniesienia: dla Railsów może to pomóc: stackoverflow.com/questions/16965697/ ...
Tilo
1
To rzeczywiście zapach kodu; jednak po przyjrzeniu się zobaczysz, że każde wyrażenie regularne jest dość zwięzłe. Problem polega na tym, że istnieją różne wzorce tworzone przez „kompresję” ipv6 - dwukropek na początku, w środku i na końcu, a jeśli użyłeś podwójnego dwukropka, nie możesz go użyć ponownie, na szczycie sumy dwukropki przed i po podwójnym muszą się sumować. Perl 6 może sobie z tym poradzić, ale wykracza to daleko poza składnię PCRE. (PS - nie liczę osadzonego ipv4 na końcu, który jest dłuższy niż sekcja ipv6!)
Gerard ONeill
11

Musiałbym zdecydowanie poprzeć odpowiedź Franka Kruegera .

Chociaż mówisz, że potrzebujesz wyrażenia regularnego, aby dopasować adres IPv6, zakładam, że to, czego naprawdę potrzebujesz, to możliwość sprawdzenia, czy dany ciąg jest prawidłowym adresem IPv6. Jest tutaj subtelna, ale ważna różnica.

Istnieje więcej niż jeden sposób sprawdzenia, czy dany ciąg jest prawidłowym adresem IPv6, a dopasowanie wyrażeń regularnych to tylko jedno rozwiązanie.

Jeśli możesz, użyj istniejącej biblioteki. Biblioteka będzie miała mniej błędów, a jej użycie spowoduje mniejszą ilość kodu do utrzymania.

Wyrażenie regularne sugerowane przez Factor Mystic jest długie i złożone. Najprawdopodobniej działa, ale powinieneś również rozważyć, jak sobie poradzisz, jeśli niespodziewanie zawiedzie. Chodzi mi o to, że jeśli nie możesz samodzielnie utworzyć wymaganego wyrażenia regularnego, nie będziesz w stanie go łatwo debugować.

Jeśli nie masz odpowiedniej biblioteki, może lepiej napisać własną procedurę walidacji IPv6, która nie zależy od wyrażeń regularnych. Jeśli to piszesz, rozumiesz, a jeśli rozumiesz, możesz dodać komentarze, aby to wyjaśnić, aby inni również mogli to zrozumieć, a następnie zachować.

Zachowaj ostrożność, używając wyrażenia regularnego, którego funkcjonalności nie możesz wyjaśnić komuś innemu.

Jon Cram
źródło
1
Użycie dwóch wyrażeń regularnych, wyrażenia liberalnego i wyrażenia wyjątków do przechwytywania nieprawidłowych adresów dozwolonych przez pierwsze, może być łatwiejsze niż jedno wyrażenie ( return ex1.match(S) && ! ex2.match(S)).
Raedwald
4
Zakładasz, że sprawdza poprawność poszczególnych adresów IP, podczas gdy prawie na pewno szuka adresów IP w dużym bloku tekstu.
Navin
8

Nie jestem ekspertem w dziedzinie IPv6, ale myślę, że dzięki temu łatwiej uzyskasz całkiem dobry wynik:

^([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})$

aby odpowiedzieć „jest prawidłowym ipv6”, wydaje mi się, że jest ok. Aby rozbić to na części ... zapomnij o tym. Pominąłem nieokreślony (: :), ponieważ nie ma sensu mieć „nieokreślonego adresu” w mojej bazie danych.

początek: ^([0-9A-Fa-f]{0,4}:){2,7}<- dopasuj część ściśliwą, możemy to przetłumaczyć jako: od 2 do 7 dwukropków, między którymi może znajdować się liczba heaksadecymalna.

po którym następuje: [0-9A-Fa-f]{1,4}$<- liczba szesnastkowa (z pominięciem wiodących 0) LUB ((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}<- adres IPv4

Remi Morin
źródło
1
+1 za trzymanie się pytania PO i prezentowanie stosunkowo przystojnego wyrażenia regularnego, które w pewnym sensie działa.
xebeche
1
To nie pasuje do „:: 1”
lsalamon
Co? W składni wyrażeń regularnych java pasuje:start() = 0, end() = 3 group(0) = "::1" group(1) = ":" group(2) = "1" group(3) = "null" group(4) = "null" group(5) = "null"
Remi Morin
Gdzie indziej ktoś powiadomił mnie o problemie z moim wyrażeniem regularnym, skompresowana część „::” może pojawić się tylko raz. Zatem „:: 1 :: 2” pasowałoby do mojego wyrażenia regularnego, ale nie jest to poprawny IPV6. Drugie wyrażenie regularne może zweryfikować ten przypadek. Pełną rekomendacją było użycie parsera stanowego do walidacji. Zgadzam się, że wynikowy kod będzie łatwiejszy do odczytania i utrzymania (a ktoś prawdopodobnie już zakodował go gdzieś w open source).
Remi Morin
8

To wychwytuje również pętlę zwrotną (:: 1) i adresy IPv6. zmieniono {} na + i wstawiono: w pierwszym nawiasie kwadratowym.

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

testowane z ifconfig -a output http://regexr.com/

Opcja terminala Unix lub Mac OSx o zwraca tylko pasujące wyjście (ipv6), w tym :: 1

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

Uzyskaj wszystkie adresy IP (IPv4 LUB IPv6) i wydrukuj dopasowanie pod terminem unix OSx

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
źródło
Podoba mi się prostota. To w końcu zadziałało dla mnie:ip a | grep -Po '[\w:]+:+[\w:]+'
Noam Manos
Humor doceniony!
Soumya Kanti
Kiedy uruchamiam ipconfig / all, mój adres IP kończy się na% 10, to wyrażenie nie pasuje do tej części?
Piotr
7

To wyrażenie regularne dopasuje prawidłowe adresy IPv6 i IPv4 zgodnie z implementacją wyrażenia regularnego w GNU C ++ z użyciem trybu REGULAR EXTENDED:

"^\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
źródło
5

Strzec się! W Javie użycie InetAddress i powiązanych klas (Inet4Address, Inet6Address, URL) może wiązać się z ruchem sieciowym! Np. Rozwiązywanie DNS (URL.equals, InetAddress z ciągu!). To połączenie może zająć dużo czasu i jest blokowane!

Dla IPv6 mam coś takiego. To oczywiście nie obsługuje bardzo subtelnych szczegółów IPv6, takich jak to, że indeksy stref są dozwolone tylko w niektórych klasach adresów IPv6. A to wyrażenie regularne nie zostało napisane do przechwytywania grupowego, jest to tylko rodzaj wyrażenia regularnego typu „dopasowuje”.

S - segment 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})

Schemat (pierwsza część odpowiada adresom IPv6 z sufiksem IPv4, druga część odpowiada adresom IPv6, ostatni wzór to indeks strefy):

(
(
::(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]+)?

A tutaj wyrażenie may regex (bez rozróżniania wielkości liter, otaczaj tym, co kiedykolwiek było potrzebne, jak początek / koniec wiersza itp.)

(?:
(?:
::(?:[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]+)?
user2623580
źródło
4

Poniższe wyrażenie regularne dotyczy tylko protokołu IPv6. Grupa 1 pasuje do adresu IP.

(([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4})
Jitendra Gosavi
źródło
+1 Nie zawsze jest konieczne posiadanie doskonałego, super złożonego wyrażenia regularnego, którego człowiek nie może zrozumieć. Użyję tego, ponieważ rozumiem, do czego służy, aw moim przypadku mogę być pewien, że jeśli mam coś, co przypomina prawidłowe IPv6, to jest to prawidłowe IPv6.
David L.
3
to nie pasuje, powiedz: fe80 :: 1 lub 2342: 32fd :: 2d32
James
3

Prosty regex, który będzie pasował, ale nie polecałbym żadnej weryfikacji, jest następujący:

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

Zauważ, że dopasowuje kompresję w dowolnym miejscu adresu, chociaż nie będzie pasować do adresu sprzężenia zwrotnego :: 1. Uważam to za rozsądny kompromis, aby zachować prostotę wyrażenia regularnego.

Z powodzeniem używam tego w regułach inteligentnego wyboru iTerm2 , aby czterokrotnie kliknąć adresy IPv6.

JinnKo
źródło
3
Miałeś na myśli A-F, nie A-Z! Pamiętaj również, że wykluczasz notację z kropkami i czwórkami.
xebeche
3

Jeśli używasz Perla, spróbuj 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);

Sprawdź poprawność :: IP

use Validate::IP qw'is_ipv6';

if( is_ipv6($ip_address) ){
  print "Looks like an ipv6 address\n";
}
Brad Gilbert
źródło
2

W Scali użyj dobrze znanych walidatorów Apache Commons.

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)

Po przeprowadzeniu testu metody 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
źródło
Interesujące, twierdzi, że sprawdza, czy jest to prawidłowy adres, „ Sprawdza, czy przekazany adres IP jest prawidłowym adresem IPv4 lub IPv6 ”, ale tak naprawdę sprawdza tylko, czy jest sformatowany jako prawidłowy adres. Na przykład 1200:0000:AB00:1234:0000:2552:7777:1313jest prawidłowym formatem adresu IPv6, ale nie jest prawidłowym adresem IPv6 zwracanym przez metodę testową. Założę się, że uważa, że 241.54.113.65to prawidłowy adres IPv4.
Ron Maupin
2

Patrząc na wzorce zawarte w innych odpowiedziach, istnieje wiele dobrych wzorców, które można poprawić, odwołując się do grup i stosując lookahead. Oto przykład wzorca odwołującego się do siebie, którego użyłbym w PHP, gdybym musiał:

^(?<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))$

Uwaga: PHP ma wbudowany filtr, który byłby lepszym rozwiązaniem niż ten wzorzec.

Analiza Regex101

Steve Buzonas
źródło
2

Wygenerowałem następujące przy użyciu Pythona i współpracuję z modułem re. Asercje przewidujące zapewniają, że w adresie pojawi się prawidłowa liczba kropek lub dwukropków. Nie obsługuje protokołu IPv4 w notacji 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
źródło
2

Regeksy dla ipv6 mogą być naprawdę trudne, jeśli weźmie się pod uwagę adresy z osadzonym ipv4 i adresy, które są skompresowane, jak widać w niektórych z tych odpowiedzi.

Biblioteka Java typu open source IPAddress zweryfikuje wszystkie standardowe reprezentacje IPv6 i IPv4, a także obsługuje długość prefiksu (i jej walidację). Zastrzeżenie: jestem kierownikiem projektu tej biblioteki.

Przykład kodu:

        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.
źródło
1

W Javie możesz użyć klasy bibliotecznej sun.net.util.IPAddressUtil:

IPAddressUtil.isIPv6LiteralAddress(iPaddress);
user463639
źródło
3
sun.net. * to prywatny interfejs API.
David Kocher
1

Trudno jest znaleźć wyrażenie regularne, które działa we wszystkich przypadkach IPv6. Zwykle są trudne w utrzymaniu, nieczytelne i mogą powodować problemy z wydajnością. Dlatego chcę udostępnić alternatywne rozwiązanie, które opracowałem: Wyrażenie regularne (RegEx) dla IPv6 Oddzielone od IPv4

Teraz możesz zapytać: „Ta metoda znajduje tylko IPv6, jak mogę znaleźć IPv6 w tekście lub pliku?” Oto metody rozwiązania tego problemu.

Uwaga : Jeśli nie chcesz używać klasy IPAddress w .NET, możesz również zastąpić ją moją metodą . Obejmuje również mapowany adres IPv4 i przypadki specjalne, podczas gdy adres IP nie obejmuje.

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
źródło
1

InetAddressUtilsma zdefiniowane wszystkie wzorce. Skończyło się na tym, że użyłem ich wzoru bezpośrednio i wklejam go tutaj w celach informacyjnych:

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 
user4604205
źródło
1

Używasz Rubiego? Spróbuj tego:

/^(((?=.*(::))(?!.*\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
źródło
1

W zależności od potrzeb przybliżenie takie jak:

[0-9a-f:]+

może wystarczyć (jak na przykład w przypadku prostego grepowania pliku dziennika).

Bill Lipa
źródło
0

Dla użytkowników PHP 5.2+ filter_vardziała świetnie.

Wiem, że to nie odpowiada na pierwotne pytanie (konkretnie na rozwiązanie regex), ale publikuję to w nadziei, że może to pomóc komuś innemu w przyszłości.

$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
źródło
0

To zadziała w przypadku IPv4 i IPv6:

^(([0-9a-f]{0,4}:){1,7}[0-9a-f]{1,4}|([0-9]{1,3}\.){3}[0-9]{1,3})$
Chris
źródło
2
Dopasowuje nieprawidłowe adresy z 2 wystąpieniami ::. np.2404:6800::4003:c02::8a
nhahtdh
pasuje do nieprawidłowego IPv4 666.666.666.666
Ryan Williams
0

Oto, co wymyśliłem, używając odrobiny wyprzedzenia i nazwanych grup. To oczywiście tylko IPv6, ale nie powinno kolidować z dodatkowymi wzorcami, jeśli chcesz dodać 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})
user1977022
źródło
0

Możesz użyć narzędzi powłoki ipextract, które stworzyłem do tego celu. Opierają się na wyrażeniach regularnych i grep.

Stosowanie:

$ ifconfig | ipextract6
fe80::1%lo0
::1
fe80::7ed1:c3ff:feec:dee1%en0
Phil L.
źródło
0

Po prostu dopasuj lokalne z pochodzenia z dołączonymi nawiasami kwadratowymi. Wiem, że nie jest to tak kompleksowe, ale w javascript inne problemy miały trudne do wyśledzenia problemy, przede wszystkim te, które nie działały, więc wydaje mi się, że teraz dostałem to, czego potrzebowałem. dodatkowe litery AF też nie są potrzebne.

^\[([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})\]

Wersja Jinnko jest uproszczona i lepiej widzę.

Mistrz James
źródło
0

Jak wspomniano powyżej, innym sposobem uzyskania tekstowej reprezentacji parsera sprawdzającego poprawność reprezentacji tekstowej IPv6 jest użycie programowania. Oto taki, który jest w pełni zgodny z RFC-4291 i RFC-5952. Napisałem ten kod w ANSI C (działa z GCC, przeszedł testy na Linuksie - działa z clang, zdał testy na FreeBSD). Dlatego opiera się tylko na standardowej bibliotece ANSI C, więc można ją skompilować wszędzie (użyłem jej do analizowania IPv6 wewnątrz modułu jądra we 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
źródło
-1

Wypróbuj ten mały, jednoliniowy. Powinien pasować tylko do prawidłowych nieskompresowanych / skompresowanych adresów IPv6 (bez hybryd 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
źródło
W rzeczywistości prawidłowe adresy IPv6 obejmują nieskompresowane, skompresowane, nieskompresowane hybrydy i skompresowane hybrydy. Naprawdę potrzeba dużo więcej niż to, co faktycznie musisz dopasować do jakiejkolwiek prawidłowej reprezentacji tekstowej adresu IPv6.
Ron Maupin
-2

Wyrażenie regularne umożliwia użycie wiodących zer w częściach IPv4.

Niektóre dystrybucje systemów Unix i Mac konwertują te segmenty na ósemki.

Sugeruję użycie 25[0-5]|2[0-4]\d|1\d\d|[1-9]?\djako segmentu IPv4.

Aeron
źródło
-2

Jeśli chcesz tylko normalne adresy IP (bez ukośników), tutaj:

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

Używam go do podświetlania składni w aplikacji edytora plików hostów. Działa jak urok.

Złupić
źródło
Nie ma mowy, żeby to kiedykolwiek działało przyzwoicie, nie może dopasować pojedynczego adresu IPv6 do pojedynczego dwukropka, wszystkie twoje dopasowania są w podwójnych dwukropkach, a ty wyraźnie potrzebujesz podwójnego dwukropka dla swojej ostatniej grupy, podsumowanie może się zdarzyć wszędzie. .
KillianDS,
(?: [0-9a-f] {1,4} (? :::?)?) {0,7} ::? [0-9a-f] {1,4}
Harry,
Wciąż źle, ale nawet wtedy powtórzysz odpowiedź JinnKo, która jest wystarczająco dobra do prostych celów, ale nadal ma wady (nie łapie podwójnego podsumowania i nie pozwala na czwórki z kropkami, localhost ani :: terminination,. ..)
KillianDS,