2017-07-26 45 views
1

我想写一个正则表达式,它将检查IP是否有效或不。表面问题当我给256值,它仍然匹配2,和REG将存储值作为1,因为模式匹配。tcl正则表达式匹配ip地址在单行

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

我不会推荐在这种情况下使用正则表达式。使用正则表达式实际上会降低性能。签出https://stackoverflow.com/questions/15587213/regex-for-a-number-greater-than-x-and-less-than-y – Tejus

回答

0

的转义.将匹配任何性格,不只是一个象征.。捕捉组是不必要的,因为你只对整个比赛感兴趣。此外,由于您要验证单个字符串,因此不需要使用-all

使用

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" 
} 

online Tcl demo

图案的详细资料

  • ^ - 串
  • (?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])的开始 - 从0第一个八位字节匹配编号,以255
  • (?:\.(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3} - 3 .(参见\.)和八位位组的出现子模式
  • $ - 结束串。
+0

谢谢。这是工作。 请您详细说明(?:)和{3}将如何在上述解决方案中工作。 –

+0

这些已被解释。参见[*什么是非捕获组?问号后面跟冒号(?:)是什么意思?*](https://stackoverflow.com/questions/3512471)以及关于[**限量词**]的信息(http://www.regular- expressions.info/repeat.html#limit)。此外,请参阅我以前的答案[* tcl regexp中的'?:'用法](https://stackoverflow.com/questions/38438851/use-case-for-in-tcl-regexp/38453664#38453664) 。 –

0

对于非常复杂的正则表达式,它摔成了碎片有助于可读性:

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

注意,您正则表达式不匹配八位字节10至99或0

测试

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