Regulärer Ausdruck, der mit gültigen IPv6-Adressen übereinstimmt

111

Ich habe Probleme beim Schreiben eines regulären Ausdrucks, der mit gültigen IPv6-Adressen übereinstimmt, einschließlich solcher in ihrer komprimierten Form (wobei in ::jedem Bytepaar Nullen oder führende Nullen weggelassen werden).

Kann jemand einen regulären Ausdruck vorschlagen, der die Anforderung erfüllt?

Ich denke darüber nach, jedes Bytepaar zu erweitern und das Ergebnis mit einem einfacheren regulären Ausdruck abzugleichen.

Schreibgeschützt
quelle
1
Schauen Sie sich intermapper.com/ipv6validator an . Es enthält Links zu diesem Perl-
Testskript
Ich habe alle unten aufgeführten Antworten ausprobiert und sie funktionieren nicht für alle meine Testfälle und / oder enthalten auch IPv4, nach dem nicht gefragt wurde. Ich habe festgestellt, dass dies die sauberste Lösung ist: stackoverflow.com/a/21944928/3112803
gfrobenius

Antworten:

251

Ich konnte die Antwort von @Factor Mystic nicht für die Arbeit mit regulären POSIX-Ausdrücken erhalten, daher habe ich eine geschrieben, die mit regulären POSIX-Ausdrücken und regulären PERL-Ausdrücken funktioniert.

Es sollte passen:

Regulärer IPv6-Ausdruck:

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

Zur Vereinfachung des Lesens ist der folgende reguläre Ausdruck an wichtigen ODER-Punkten in separate Zeilen unterteilt:

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

Um das Obige leichter verständlich zu machen, repliziert der folgende "Pseudo" -Code das Obige:

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

Ich habe ein Skript auf GitHub veröffentlicht, das den regulären Ausdruck testet: https://gist.github.com/syzdek/6086792

David M. Syzdek
quelle
3
Ihr IPv4-Regex stimmt nicht mit IPs wie127.000.000.001
Kentzo
21
IPv4-Segmente sollten keine führenden Nullen enthalten. Wenn eine führende Null vorhanden ist, sollte das IPv4-Segment oktal interpretiert werden. Das IPV4SEG oben ist also richtig, wenn es nicht erlaubt, '000' zuzulassen. Es erlaubt jedoch '00', was es nicht sollte.
Par
3
Hat bei mir im Browser nicht so funktioniert, wie ich es erwartet hätte. Validiert sogar reg.test ('3zzzzffe: 1900: 4545: 3: 200: f8ff: fe21: 67cf'), was offensichtlich keine gültige IPv6-Adresse ist. Hatte viel bessere Ergebnisse mit Regex hier: nbviewer.ipython.org/github/rasbt/python_reference/blob/master/…
Capaj
7
fantastischer ipv6 regex. habe einen kleinen Fehler mit dem lokalen Linkabschnitt gefunden. Sie hatten, fe80wo es so etwas sein sollte [fF][eE]80und ffffwas so etwas sein sollte[fF]{4}
user2831628
4
+1, um zu zeigen, dass reguläre Ausdrücke (auf die gleiche Weise wie jeder Quellcode) tatsächlich lesbar sind, wenn Sie sorgfältig vorgehen und sie formatieren.
Natix
52

Im Folgenden werden die Adressen IPv4, IPv6 (vollständig und komprimiert) und IPv6v4 (vollständig und komprimiert) überprüft:

'/^(?>(?>([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'
Michael Rushton
quelle
8
Obwohl die Validierung von IP-Ss wie von Frank Krueger vorgeschlagen durchgeführt werden könnte, ist diese Lösung diejenige, die die Frage tatsächlich beantwortet (obwohl ich sie noch nicht vollständig getestet habe) und ob Sie viele IP-S haben, die Sie syntaktisch testen möchten und möglicherweise in einer Textzeile übereinstimmen, können Sie die IP-Validierungstechnik nicht verwenden.
Gyuri
Hallo, ich habe dieses RegExp getestet und nicht für mich gearbeitet. Es heißt, D sei ein ungültiges Flag, und wenn ich es entferne, steht "SyntaxError: ungültiger Quantifizierer"
Diosney
3
JavaScript implementiert eine Teilmenge regulärer Ausdrücke im Perl-Stil, nicht die Gesamtheit von PCRE. Mein regulärer Ausdruck funktioniert ohne einige der erweiterten Funktionen von PCRE nicht.
Michael
2
Dies gibt eine Ausnahme für mich in C #
Sarat
1
Fehlgeschlagener Testfall: FE80: 0000: 0000: 0000: 0202: B3FF: FE1E: 8329 Verwenden der neuesten Version von Elixir an diesem Datum, bei der PCRE darunter verwendet wird.
Pmarreck
23

Es hört sich so an, als würden Sie Python verwenden. Wenn ja, können Sie so etwas verwenden:

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

Ich glaube nicht, dass Sie IPv6 in Python kompilieren müssen, um es zu erhalten inet_pton, das auch IPv4-Adressen analysieren kann, wenn Sie socket.AF_INETals ersten Parameter übergeben. Hinweis: Dies funktioniert möglicherweise nicht auf Nicht-Unix-Systemen.

Joe Hildebrand
quelle
4
Sie sollten den Ausnahmetyp in der exceptKlausel angeben . Andernfalls exceptwird alles abgefangen und kann nicht verwandte Fehler maskieren. Der Typ hier sollte sein socket.error.
Ayman Hourieh
A) inet_pton löst keine anderen Ausnahmen aus, es sei denn, die Dokumente sind falsch, und B) selbst wenn dies der Fall wäre, was würden Sie außer False zurückgeben?
Joe Hildebrand
2
Betreff: andere Fehler ... Wenn der Benutzer eine Nicht-Zeichenfolge übergibt, wird TypeError gegessen. Natürlich ist eine Liste kein IPv6, aber ich möchte wahrscheinlich einen Karpfen haben, den ich im falschen Typ übergeben habe.
Gregg Lind
1
+1 Das hat mir sehr geholfen. Einige zusätzliche Punkte, die hinzugefügt werden sollten: 1) socket.inet_pton kann verwendet werden, um die Gültigkeit beider Familien von IP-Adressen (IP und IPv6) zu testen. 2) Die Dokumente hier ( docs.python.org/2/library/socket.html ) legen nahe, dass dies auf Unix-Plattformen verfügbar ist. Es ist möglicherweise nicht auf Win-Plattformen verfügbar.
mkoistinen
mit django und das hilft!
Elad Silber
23

Aus " 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)
Faktor Mystic
quelle
45
Ein solcher regulärer Ausdruck sollte ein "Code-Geruch" sein, der möglicherweise nicht die am besten geeignete Lösung ist. (Obwohl, ich denke, die Operation hat danach gefragt ...)
Thanatos
10
@ user712092 - jeder, der eine Codebasis mit solchen Schandflecken gesehen hat
danielpops
2
Dies ist eine völlig unnötige Travestie für REs. Das Programm, das es generiert hat, hat nicht verstanden, was es tat. Ein Mensch würde es niemals so machen. Lassen Sie sich nicht von der offensichtlichen Komplexität täuschen - REs sind für viele Menschen zwar "schwarze Magie", aber es gibt keinen Grund, sie auf einem anderen Planeten zu platzieren!
Chuck Kollars
+1 aber OMG, es muss einen besseren Weg geben, dies zu tun: P Als Referenz: Für Rails könnte dies helfen: stackoverflow.com/questions/16965697/…
Tilo
1
Es ist in der Tat ein Code-Geruch; Wenn Sie jedoch einen Blick darauf werfen, werden Sie feststellen, dass jeder reguläre Ausdruck ziemlich präzise ist. Das Problem ist, dass es verschiedene Muster gibt, die durch die 'Komprimierung' von ipv6 erstellt wurden - Doppelpunkte am Anfang, in der Mitte und am Ende. Wenn Sie Ihren Doppelpunkt verwendet haben, können Sie ihn nicht mehr verwenden, zusätzlich zur Gesamtsumme Doppelpunkte vor und nach dem Double müssen sich addieren. Perl 6 ist möglicherweise in der Lage, dies in Angriff zu nehmen, aber es geht weit über die PCRE-Syntax hinaus. (PS - Ich zähle das eingebettete IPv4 am Ende nicht, das länger ist als der IPv6-Abschnitt!)
Gerard ONeill
11

Ich müsste die Antwort von Frank Krueger stark unterstützen .

Während Sie sagen, dass Sie einen regulären Ausdruck benötigen, um mit einer IPv6-Adresse übereinzustimmen, gehe ich davon aus, dass Sie wirklich überprüfen müssen, ob eine bestimmte Zeichenfolge eine gültige IPv6-Adresse ist. Hier gibt es eine subtile, aber wichtige Unterscheidung.

Es gibt mehrere Möglichkeiten, um zu überprüfen, ob eine bestimmte Zeichenfolge eine gültige IPv6-Adresse ist, und die Übereinstimmung mit regulären Ausdrücken ist nur eine Lösung.

Verwenden Sie eine vorhandene Bibliothek, wenn Sie können. Die Bibliothek weist weniger Fehler auf und ihre Verwendung führt zu weniger Code, den Sie warten müssen.

Der von Factor Mystic vorgeschlagene reguläre Ausdruck ist lang und komplex. Es funktioniert höchstwahrscheinlich, aber Sie sollten auch überlegen, wie Sie damit umgehen würden, wenn es unerwartet fehlschlägt. Der Punkt, den ich hier ansprechen möchte, ist, dass Sie einen erforderlichen regulären Ausdruck nicht einfach debuggen können, wenn Sie ihn nicht selbst erstellen können.

Wenn Sie keine geeignete Bibliothek haben, ist es möglicherweise besser, eine eigene IPv6-Validierungsroutine zu schreiben, die nicht von regulären Ausdrücken abhängt. Wenn Sie es schreiben, verstehen Sie es und wenn Sie es verstehen, können Sie Kommentare hinzufügen, um es zu erklären, damit andere es auch verstehen und anschließend pflegen können.

Seien Sie vorsichtig, wenn Sie einen regulären Ausdruck verwenden, dessen Funktionalität Sie niemand anderem erklären können.

Jon Cram
quelle
1
Die Verwendung von zwei regulären Ausdrücken, einem liberalen Ausdruck und einem Ausnahmeausdruck zum Abfangen ungültiger Adressen, die von der ersten zugelassen werden, ist möglicherweise einfacher als ein Ausdruck ( return ex1.match(S) && ! ex2.match(S)).
Raedwald
4
Sie gehen davon aus, dass er einzelne IPs validiert, wenn er mit ziemlicher Sicherheit nach IPs in einem großen Textblock sucht.
Navin
8

Ich bin kein Ipv6-Experte, aber ich denke, mit diesem können Sie leichter ein ziemlich gutes Ergebnis erzielen:

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

zu antworten "ist ein gültiges ipv6" es sieht für mich ok aus. Um es in Teile zu zerlegen ... vergiss es. Ich habe die nicht spezifizierte Adresse (: :) weggelassen, da es keinen Sinn macht, "nicht spezifizierte Adresse" in meiner Datenbank zu haben.

Der Anfang: ^([0-9A-Fa-f]{0,4}:){2,7}<- Entspricht dem komprimierbaren Teil. Wir können dies wie folgt übersetzen: zwischen 2 und 7 Doppelpunkten, zwischen denen möglicherweise eine Heaxadezimalzahl steht.

gefolgt von: [0-9A-Fa-f]{1,4}$<- einer Hexadezimalzahl (führende 0 weggelassen) ODER ((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}<- einer Ipv4-Adresse

Remi Morin
quelle
1
+1 für das tatsächliche Festhalten an der OP-Frage und das Präsentieren eines relativ gut aussehenden regulären Ausdrucks, der etwas funktioniert.
Xebeche
1
Dies
stimmt
Huh? In Java Regex Syntaxt stimmt es überein:start() = 0, end() = 3 group(0) = "::1" group(1) = ":" group(2) = "1" group(3) = "null" group(4) = "null" group(5) = "null"
Remi Morin
An einer anderen Stelle benachrichtigt mich jemand über ein Problem mit meinem regulären Ausdruck. Der komprimierte Teil "::" kann nur einmal angezeigt werden. ":: 1 :: 2" würde also mit meinem regulären Ausdruck übereinstimmen, aber es ist kein gültiges IPV6. Ein zweiter regulärer Ausdruck kann diesen Fall validieren. Die vollständige Empfehlung lautete, zur Validierung einen Stateful-Parser zu verwenden. Ich bin damit einverstanden, dass der resultierende Code einfacher zu lesen und zu warten ist (und wahrscheinlich hat ihn jemand bereits irgendwo in einer Open Source-Version codiert).
Remi Morin
8

Dies fängt auch den Loopback (:: 1) und die IPv6-Adressen ab. änderte {} in + und setzte: in die erste eckige Klammer.

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

getestet mit ifconfig -a Ausgabe http://regexr.com/

Die Option Unix oder Mac OSx Terminal o gibt nur die übereinstimmende Ausgabe (ipv6) zurück, einschließlich :: 1

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

Holen Sie sich alle IP-Adressen (IPv4 ODER IPv6) und drucken Sie die Übereinstimmung unter 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
quelle
Ich mag die Einfachheit. Dies funktionierte schließlich für mich:ip a | grep -Po '[\w:]+:+[\w:]+'
Noam Manos
Humor geschätzt!
Soumya Kanti
Wenn ich ipconfig / all ausführe, endet meine IP-Adresse mit% 10, stimmt dieser Ausdruck nicht mit diesem Teil überein?
Peter
7

Dieser reguläre Ausdruck stimmt mit gültigen IPv6- und IPv4-Adressen gemäß der GNU C ++ - Implementierung von Regex mit dem verwendeten REGULAR EXTENDED-Modus überein:

"^\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
quelle
5

In acht nehmen! In Java kann die Verwendung von InetAddress und verwandten Klassen (Inet4Address, Inet6Address, URL) Netzwerkverkehr beinhalten! ZB DNS-Auflösung (URL.equals, InetAddress from string!). Dieser Anruf kann lange dauern und blockiert!

Für IPv6 habe ich so etwas. Dies behandelt natürlich nicht die sehr subtilen Details von IPv6, da Zonenindizes nur für einige Klassen von IPv6-Adressen zulässig sind. Und dieser reguläre Ausdruck ist nicht für die Gruppenerfassung geschrieben, sondern nur ein regulärer Ausdruck für Übereinstimmungen.

S - IPv6-Segment = [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})

Schema (erster Teil stimmt mit IPv6-Adressen mit IPv4-Suffix überein, zweiter Teil stimmt mit IPv6-Adressen überein, letzter Patrt des Zonenindex):

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

Und hier könnte der reguläre Ausdruck (Groß- und Kleinschreibung nicht berücksichtigen, umgeben mit dem, was jemals benötigt wurde, wie Anfang / Ende der Zeile usw.):

(?:
(?:
::(?:[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
quelle
4

Der folgende reguläre Ausdruck gilt nur für IPv6. Gruppe 1 stimmt mit der IP überein.

(([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4})
Jitendra Gosavi
quelle
+1 Es ist nicht immer notwendig, einen perfekten, superkomplexen regulären Ausdruck zu haben, den ein Mensch nicht verstehen kann. Ich werde dieses verwenden, weil ich verstehe, was es tut, und in meinem Fall kann ich sicher sein, dass es ein gültiges IPv6 ist, wenn ich etwas habe, das einem gültigen IPv6 ähnelt.
David L.
3
das würde nicht passen sagen: fe80 :: 1 oder 2342: 32fd :: 2d32
James
3

Ein einfacher regulärer Ausdruck, der übereinstimmt, den ich jedoch für die Validierung jeglicher Art nicht empfehlen würde, ist folgender:

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

Beachten Sie, dass dies mit der Komprimierung an einer beliebigen Stelle in der Adresse übereinstimmt, jedoch nicht mit der Loopback-Adresse :: 1. Ich halte dies für einen vernünftigen Kompromiss, um den regulären Ausdruck einfach zu halten.

Ich verwende dies erfolgreich in den Smart-Auswahlregeln von iTerm2 , um auf IPv6-Adressen zu klicken.

JinnKo
quelle
3
Du meintest A-Fnicht A-Z! Beachten Sie auch, dass Sie die Punkt-Quad-Notation ausschließen.
Xebeche
3

Wenn Sie Perl verwenden, versuchen Sie 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);

Validate :: IP

use Validate::IP qw'is_ipv6';

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

In der ScalaVerwenden Sie die bekannten Apache Commons-Validatoren.

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)

Befolgen Sie die Tests der Methode 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
quelle
Interessant, es behauptet zu überprüfen, ob es eine gültige Adresse ist, "Überprüft, ob die übergebene IP eine gültige IPv4- oder IPv6-Adresse ist. ", Aber es prüft wirklich nur, ob es als gültige Adresse formatiert ist. Dies 1200:0000:AB00:1234:0000:2552:7777:1313ist beispielsweise ein gültiges Format für eine IPv6-Adresse, jedoch keine gültige IPv6-Adresse, da die Testmethode zurückgibt. Ich wette, es 241.54.113.65ist eine gültige IPv4-Adresse.
Ron Maupin
2

Wenn man sich die in den anderen Antworten enthaltenen Muster ansieht, gibt es eine Reihe guter Muster, die durch Referenzieren von Gruppen und Verwenden von Lookaheads verbessert werden können. Hier ist ein Beispiel für ein Muster, das sich selbst referenziert und das ich in PHP verwenden würde, wenn ich müsste:

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

Hinweis: PHP verfügt über einen integrierten Filter, der eine bessere Lösung als dieses Muster darstellt.

Regex101-Analyse

Steve Buzonas
quelle
2

Ich habe folgendes mit Python generiert und arbeite mit dem Re-Modul. Die Vorausschau-Zusicherungen stellen sicher, dass die richtige Anzahl von Punkten oder Doppelpunkten in der Adresse angezeigt wird. IPv4 in IPv6-Notation wird nicht unterstützt.

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
quelle
2

Regexes für IPv6 können sehr schwierig werden, wenn Sie Adressen mit eingebettetem IPv4 und komprimierte Adressen berücksichtigen, wie Sie aus einigen dieser Antworten ersehen können.

Die Open-Source-IPAddress-Java-Bibliothek validiert alle Standarddarstellungen von IPv6 und IPv4 und unterstützt auch die Präfixlänge (und deren Validierung). Haftungsausschluss: Ich bin der Projektmanager dieser Bibliothek.

Codebeispiel:

        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.
quelle
1

In Java können Sie die Bibliotheksklasse verwenden sun.net.util.IPAddressUtil:

IPAddressUtil.isIPv6LiteralAddress(iPaddress);
user463639
quelle
3
sun.net. * ist eine private API.
David Kocher
1

Es ist schwierig, einen regulären Ausdruck zu finden, der für alle IPv6-Fälle funktioniert. Sie sind normalerweise schwer zu warten, nicht leicht lesbar und können Leistungsprobleme verursachen. Daher möchte ich eine alternative Lösung vorstellen, die ich entwickelt habe: RegEx (Regular Expression) für IPv6, getrennt von IPv4

Nun können Sie fragen: "Diese Methode findet nur IPv6. Wie kann ich IPv6 in einem Text oder einer Datei finden?" Hier finden Sie auch Methoden für dieses Problem.

Hinweis : Wenn Sie nicht IPAddress - Klasse in .NET verwenden möchten, können Sie es auch mit ersetzen meine Methode . Es werden auch zugeordnete IPv4- und Sonderfälle behandelt, während IPAddress dies nicht abdeckt.

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
quelle
1

InetAddressUtilshat alle Muster definiert. Am Ende habe ich ihr Muster direkt verwendet und füge es hier als Referenz ein:

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
quelle
1

Verwenden Sie Ruby? Versuche dies:

/^(((?=.*(::))(?!.*\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
quelle
1

Abhängig von Ihren Bedürfnissen kann eine Annäherung wie:

[0-9a-f:]+

kann ausreichen (wie zum Beispiel beim einfachen Greppen von Protokolldateien).

Bill Lipa
quelle
0

Für PHP 5.2+ filter_varfunktionieren Benutzer hervorragend.

Ich weiß, dass dies nicht die ursprüngliche Frage beantwortet (speziell eine Regex-Lösung), aber ich poste dies in der Hoffnung, dass es in Zukunft jemand anderem helfen kann.

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

Dies funktioniert für IPv4 und IPv6:

^(([0-9a-f]{0,4}:){1,7}[0-9a-f]{1,4}|([0-9]{1,3}\.){3}[0-9]{1,3})$
Chris
quelle
2
Es vergleicht ungültige Adressen mit 2 Instanzen von ::. zB2404:6800::4003:c02::8a
nhahtdh
Übereinstimmungen ungültig IPv4 666.666.666.666
Ryan Williams
0

Hier ist, was ich mir ausgedacht habe, mit ein bisschen Lookahead und benannten Gruppen. Dies ist natürlich nur IPv6, sollte jedoch zusätzliche Muster nicht beeinträchtigen, wenn Sie IPv4 hinzufügen möchten:

(?=([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
quelle
0

Sie können die ipextract-Shell-Tools verwenden ich für diesen Zweck erstellt habe. Sie basieren auf Regexp und Grep.

Verwendung:

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

Nur passende lokale von einem Ursprung mit eckigen Klammern enthalten. Ich weiß, dass es nicht so umfassend ist, aber in Javascript hatten die anderen Schwierigkeiten, Probleme zu verfolgen, vor allem die, nicht zu funktionieren. Das scheint mir das zu bringen, was ich jetzt brauchte. AF mit zusätzlichen Hauptstädten wird ebenfalls nicht benötigt.

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

Jinnkos Version ist vereinfacht und besser sehe ich.

Meister James
quelle
0

Wie oben erwähnt, besteht eine andere Möglichkeit, einen Parser zur Überprüfung der IPv6-Textdarstellung zu erhalten, in der Programmierung. Hier ist eine, die vollständig mit RFC-4291 und RFC-5952 kompatibel ist. Ich habe diesen Code in ANSI C geschrieben (funktioniert mit GCC, hat Tests unter Linux bestanden - funktioniert mit Clang, hat Tests unter FreeBSD bestanden). Daher ist es nur auf die ANSI C-Standardbibliothek angewiesen, sodass es überall kompiliert werden kann (ich habe es für die IPv6-Analyse in einem Kernelmodul mit FreeBSD verwendet).

// 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
quelle
-1

Probieren Sie diesen kleinen Einzeiler. Es sollte nur mit gültigen unkomprimierten / komprimierten IPv6-Adressen übereinstimmen (keine IPv4-Hybride).

/(?!.*::.*::)(?!.*:::.*)(?!:[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
quelle
Gültige IPv6-Adressen umfassen unkomprimierte, komprimierte, unkomprimierte Hybride und komprimierte Hybriden. Es braucht wirklich viel mehr als das, was Sie benötigen, um einer gültigen Textdarstellung einer IPv6-Adresse zu entsprechen.
Ron Maupin
-2

Der reguläre Ausdruck ermöglicht die Verwendung führender Nullen in den IPv4-Teilen.

Einige Unix- und Mac-Distributionen konvertieren diese Segmente in Oktale.

Ich schlage vor, 25[0-5]|2[0-4]\d|1\d\d|[1-9]?\dals IPv4-Segment zu verwenden.

Aeron
quelle
-2

Wenn Sie nur normale IP-Adressen (keine Schrägstriche) möchten, hier:

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

Ich verwende es für meinen Syntax-Textmarker in der Hosts-Datei-Editor-Anwendung. Wirkt als Charme.

Harry
quelle
Auf keinen Fall funktioniert dies jemals anständig, es kann keine einzelne IPv6-Adresse mit einem einzelnen Doppelpunkt darin übereinstimmen, alle Ihre Übereinstimmungen befinden sich in doppelten Doppelpunkten, und Sie benötigen explizit einen doppelten Doppelpunkt für Ihre letzte Gruppe. Eine Zusammenfassung kann überall erfolgen. ...
KillianDS
(?: [0-9a-f] {1,4} (? :::?)?) {0,7} ::? [0-9a-f] {1,4}
Harry
Immer noch falsch, aber selbst dann wiederholen Sie am Ende die Antwort von JinnKo, die für einfache Zwecke gut genug ist, aber dennoch Fehler aufweist (keine doppelte Zusammenfassung und keine gepunkteten Quads, weder localhost noch :: terminierung) zulässt. ..)
KillianDS