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.
regex
networking
ipv6
Tylko czytać
źródło
źródło
Odpowiedzi:
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:
Dla ułatwienia czytania, poniższe wyrażenie regularne zostało podzielone w głównych punktach LUB na osobne wiersze:
Aby ułatwić zrozumienie powyższego, poniższy „pseudo” kod powiela powyższy:
Opublikowałem skrypt na GitHubie, który testuje wyrażenie regularne: https://gist.github.com/syzdek/6086792
źródło
127.000.000.001
fe80
gdzie powinno być coś takiego,[fF][eE]80
affff
które powinno być jakoś[fF]{4}
Poniższe czynności sprawdzą poprawność adresów IPv4, IPv6 (pełne i skompresowane) oraz IPv6v4 (pełne i skompresowane):
źródło
Wygląda na to, że używasz Pythona. Jeśli tak, możesz użyć czegoś takiego:
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 podaszsocket.AF_INET
jako pierwszy parametr. Uwaga: to może nie działać na systemach innych niż Unix.źródło
except
klauzuli należy określić typ wyjątku . W przeciwnym razieexcept
przechwyci wszystko i może maskować niepowiązane błędy. Powinien to być typsocket.error
.Z „ IPv6 regex ”:
źródło
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.
źródło
return ex1.match(S) && ! ex2.match(S)
).Nie jestem ekspertem w dziedzinie IPv6, ale myślę, że dzięki temu łatwiej uzyskasz całkiem dobry wynik:
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źródło
start() = 0, end() = 3 group(0) = "::1" group(1) = ":" group(2) = "1" group(3) = "null" group(4) = "null" group(5) = "null"
To wychwytuje również pętlę zwrotną (:: 1) i adresy IPv6. zmieniono {} na + i wstawiono: w pierwszym nawiasie kwadratowym.
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
Uzyskaj wszystkie adresy IP (IPv4 LUB IPv6) i wydrukuj dopasowanie pod terminem unix OSx
źródło
ip a | grep -Po '[\w:]+:+[\w:]+'
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:
źródło
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):
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.)
źródło
Poniższe wyrażenie regularne dotyczy tylko protokołu IPv6. Grupa 1 pasuje do adresu IP.
źródło
Prosty regex, który będzie pasował, ale nie polecałbym żadnej weryfikacji, jest następujący:
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.
źródło
A-F
, nieA-Z
! Pamiętaj również, że wykluczasz notację z kropkami i czwórkami.Jeśli używasz Perla, spróbuj Net :: IPv6Addr
NetAddr :: IP
Sprawdź poprawność :: IP
źródło
W Scali użyj dobrze znanych walidatorów Apache Commons.
http://mvnrepository.com/artifact/commons-validator/commons-validator/1.4.1
Po przeprowadzeniu testu metody
ip(ip: String)
:źródło
1200:0000:AB00:1234:0000:2552:7777:1313
jest prawidłowym formatem adresu IPv6, ale nie jest prawidłowym adresem IPv6 zwracanym przez metodę testową. Założę się, że uważa, że241.54.113.65
to prawidłowy adres IPv4.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ł:
Uwaga: PHP ma wbudowany filtr, który byłby lepszym rozwiązaniem niż ten wzorzec.
Analiza Regex101
źródło
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.
źródło
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:
źródło
W Javie możesz użyć klasy bibliotecznej
sun.net.util.IPAddressUtil
:źródło
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.
źródło
InetAddressUtils
ma zdefiniowane wszystkie wzorce. Skończyło się na tym, że użyłem ich wzoru bezpośrednio i wklejam go tutaj w celach informacyjnych:źródło
Używasz Rubiego? Spróbuj tego:
źródło
W zależności od potrzeb przybliżenie takie jak:
może wystarczyć (jak na przykład w przypadku prostego grepowania pliku dziennika).
źródło
Dla użytkowników PHP 5.2+
filter_var
dział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.
źródło
To zadziała w przypadku IPv4 i IPv6:
źródło
::
. np.2404:6800::4003:c02::8a
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:
źródło
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:
źródło
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.
Wersja Jinnko jest uproszczona i lepiej widzę.
źródło
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).
źródło
Wypróbuj ten mały, jednoliniowy. Powinien pasować tylko do prawidłowych nieskompresowanych / skompresowanych adresów IPv6 (bez hybryd IPv4)
źródło
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]?\d
jako segmentu IPv4.źródło
Jeśli chcesz tylko normalne adresy IP (bez ukośników), tutaj:
Używam go do podświetlania składni w aplikacji edytora plików hostów. Działa jak urok.
źródło