2017-07-26 10 views
1

J'essaye d'écrire une expression rationnelle qui vérifiera si l'adresse IP est valide ou non.Face problème quand je donne 256 comme valeur il est toujours correspondant à 2, et reg va stocker la valeur comme 1 puisque le motif est apparié.tcl regex correspond à l'adresse IP dans une seule ligne

set ip "256.256.255.1" 
set reg [regexp -all{^([1-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]).([1-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]).([1-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]).([1-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])} $ip match ] 
puts $reg 
+1

Je ne recommanderais pas d'utiliser l'expression régulière pour ce cas. Utiliser une expression régulière réduira réellement les performances. Consultez https://stackoverflow.com/questions/15587213/regex-for-a-number-greater-than-x-and-less-than-y – Tejus

Répondre

0

Le . correspondront non échappés tout caractère, pas seulement un symbole .. Les groupes de capture sont inutiles puisque vous êtes seulement intéressé par un match entier. En outre, pas besoin d'utiliser -all puisque vous voulez valider une seule chaîne.

Utilisez

set text {256.256.255.1} 
set pattern {^(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}$} 
regexp $pattern $text match 
if {[info exists match]} { 
    puts $match 
} else { 
    puts "No match" 
} 

Voir la online Tcl demo.

Motif détails:

  • ^ - début de chaîne
  • (?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]) - premiers nombres correspondants d'octets 0-255
  • (?:\.(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3} - 3 occurrences d'un . (voir \.) et l'octet sous-modèle
  • $ - fin de chaîne.
+0

Merci. Ça fonctionne. Pourriez-vous préciser comment (? :) et {3} fonctionneront dans la solution mentionnée ci-dessus. –

+0

Ceux-ci ont déjà été expliqués. Voir [* Qu'est-ce qu'un groupe qui ne capture pas? Que signifie un point d'interrogation suivi d'un deux-points (? :) signifie? *] (Https://stackoverflow.com/questions/3512471) et d'informations sur [** quantificateurs limitants **] (http: //www.regular- expressions.info/repeat.html#limit). Aussi, voir ma réponse précédente à [* cas d'utilisation pour '?:' Dans tcl regexp *] (https://stackoverflow.com/questions/38438851/use-case-for-in-tcl-regexp/38453664#38453664) . –

0

Pour regexes très compliquées, brisant en morceaux d'améliorer la lisibilité:

set octet {(?:[1-9]?[0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])} 
set ip_re [format {\m%s\.%s\.%s\.%s\M} {*}[lrepeat 4 $octet]] 

Notez votre regex ne correspond pas à octets 10 à 99 ou 0.

test

set str "hello 1.2.3.4 there 127.0.0.1 friend 256.9.99.999 x255.255.255.255" 
regexp -all $ip_re $str    ;# => 2 
regexp -all -inline $ip_re $str  ;# => 1.2.3.4 127.0.0.1