2016-04-12 60 views
1

我必須分配IP地址和端口,並使用此代碼在正則表達式設置變量與零或一匹配

set str 192.168.1.1:44 
set port 23 
regexp {(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}):(\d+)?} $str all ip port 
puts $ip 
puts $port 

而且它完美的作品。但如果使用$ str沒有端口(例如192.168.1.1),則沒有設置變量並且TCL返回錯誤。

can't read "ip": no such variable 

正則表達式「192.168.1.1」仍然匹配沒有端口(我和「if」語句檢查的話),沒有港口,但爲何它沒有返回變量?我期望$ all和$ ip。

+1

它應該是'(:\ d +)'..你需要做'colon'可選 – rock321987

回答

1

你應該讓冒號可選,並在不同的組中捕獲正則表達式。

正則表達式:^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(?::?(\d+))?$

說明:

  • IP地址在第一組捕獲。

  • 可選端口號在第二組中捕獲。 :是非捕獲組的一部分,因此它不會被捕獲到第二組中。

Regex101 Demo

+0

謝謝...我?真的很困惑。當然,它解決了。我檢查的if語句的括號中包含冒號,所以它讓我問一個問題:( –

+0

從技術上講,這將匹配一個IP與尾隨冒號但沒有端口 - 「192.168.1.1:」。 – bipll

+0

@bipll:更新我的答案。 –

2
set str 192.168.1.1:44 
lassign [split $str :] ip port 
if {$port eq ""} { 
    set port 23 
} 
puts $ip 
puts $port 

如果需要驗證$ip字符串是一個有效的IP地址,最好使用ip包不是一個正則表達式(正則表達式你使用的將會接受很多無效的IP地址)。

請注意,您將遇到很多IPv6地址問題。

文檔:iflassignputssetsplitip

+0

ip包可能使用正則表達式,但它使用正確的,已經被調試對一堆真正討厭的測試用例 –

+0

@DonalFellows:包中有三個正則表達式的調用,它們的範圍非常明顯,regu沒有錯但我發現他們經常被懶散地和天真地使用。 –