2017-07-26 66 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