Come posso abbinare gli indirizzi IPv6 con un regex Perl?
Domanda
Quindi devo abbinare un indirizzo ipv6 che può avere o meno una maschera. Sfortunatamente non posso semplicemente usare una libreria per analizzare la stringa.
Il bit della maschera è abbastanza facile, in questo caso:
(?:\/\d{1,3})?$/
La parte difficile sono i diversi formati di un indirizzo ipv6. Deve corrispondere :: manzo, manzo ::, manzo :: manzo, ecc.
Un aggiornamento: ci sono quasi ..
/^(\:\:([a-f0-9]{1,4}\:){0,6}?[a-f0-9]{0,4}|[a-f0-9]{1,4}(\:[a-f0-9]{1,4}){0,6}?\:\:|[a-f0-9]{1,4}(\:[a-f0-9]{1,4}){1,6}?\:\:([a-f0-9]{1,4}\:){1,6}?[a-f0-9]{1,4})(\/\d{1,3})?$/i
In questo caso, sono limitato all'utilizzo della regex di perl.
Soluzione
Questo contiene una patch per Regexp :: Common dimostrative un regex IPv6 completo, accurato e testato. È una traduzione diretta della grammatica IPv6. Regexp :: IPv6 è anche preciso.
Ancora più importante, contiene una suite di test. Eseguirlo con regex mostra che sei ancora lontana. 10 su 19 persi. 1 su 12 falsi positivi. IPv6 contiene molte scorciatoie speciali che rendono molto facile sbagliare sottilmente.
Il posto migliore per leggere ciò che entra in un indirizzo IPv6 è la sezione RFC 3986 3.2.2.
Altri suggerimenti
Cosa vuoi dire con cui non puoi semplicemente usare una libreria? Che ne dici di un modulo? Regexp :: IPv6
ti darà ciò di cui hai bisogno .
Non sono un esperto di IPv6, ma ti prego, fidati di me quando ti dico che la corrispondenza (per non parlare della convalida) degli indirizzi IPv6 non è facile con una regex molto semplice come quella che suggerisci. Ci sono molte scorciatoie e varie convenzioni per combinare l'indirizzo con una porta, solo per citarne un esempio. Una di queste scorciatoie è che puoi scrivere 0: 0: 0: 0: 0: 0: 0: 1 come :: 1, ma c'è di più. Se leggi il tedesco, suggerirei di guardare le diapositive di Discorso di Steffen Ullrich all'undicesimo seminario tedesco Perl.
Dici che non puoi usare una biblioteca, ma se hai intenzione di reinventare l'intera complessità della biblioteca, puoi anche importarla alla lettera nel tuo progetto.
Funziona principalmente ...
^([0-9a-fA-F]{0,4}|0)(\:([0-9a-fA-F]{0,4}|0)){7}$
Contro: ::
come casi non gestiti correttamente
Prova questo:
^([0-9a-fA-F]{4}|0)(\:([0-9a-fA-F]{4}|0)){7}$
Da Libreria di espressioni regolari: indirizzo IPv6
Dovresti anche leggere questo: Un'espressione regolare per gli indirizzi IPv6
Se hai bisogno in perl controlla se una stringa è un indirizzo IPv6 puoi provare questo:
if (/(([\da-f]{0,4}:{0,2}){1,8})/i) { print("$1") };
Prova:
/^(((?=(?>.*?(::))(?!.+\3)))\3?|([\dA-F]{1,4}(\3|:(?!$)|$)|\2))(?4){5}((?4){2}|((2[0-4]|1\d|[1-9])?\d|25[0-5])(\.(?7)){3})\z/ai
ecco quello che ha funzionato per tutti gli esempi di IPv6 che sono riuscito a trovare:
/^\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]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){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]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){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]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){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]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){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]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/
assicurati che sia l'unica riga prima dell'uso. è stato trovato qui:
verificato su tutti gli esempi dalla pagina delle domande, dalla pagina della community e dal sito di Wikipedia da qui:
https://en.wikipedia.org/wiki/IPv6
lo strumento per la verifica utilizzato quello da qui: