我有这个文件:
#2/1/1/21=p1 5/1/1/21=p1 isid=104
3/1/1/9=p1 4/1/1/4=p1 5/1/1/17=p1 6/1/1/4=p1 isid=100
1/1/1/4=p1 6/1/1/5=p1 isid=101
我希望忽略第1行(它是注释行) 在第二行我想在三个变量var1 var2和var3中得到“3/1/1/9”“4/1/1/4”“5/1/1/17” 在第三行中,我想在两个变量var1和var2中得到“1/1/1/4”和“6/1/1/5”。
目前我可以忽略第1行,并在第2行或第3行匹配我想要的内容:
if {[regexp {^(\d/\d/\d/\d{1,2})=p1.*(\d/\d/\d/\d{1,2})=p1} $line value match1 match2]} {
# This works for line 3 but not line 2
}
if {[regexp {^(\d/\d/\d/\d{1,2})=p1.*(\d/\d/\d/\d{1,2})=p1.*(\d/\d/\d/\d{1,2})=p1} $line value match1 match2 match3]} {
# This works for line 2 but not line 3
}
如何为第2行和第3行匹配正确的数量?
答案 0 :(得分:2)
试试这个正则表达式:
[regexp {^(\d/\d/\d/\d{1,2})=p1.*?(\d/\d/\d/\d{1,2})=p1(?:.*?(\d/\d/\d/\d{1,2})=p1)?} $line value match1 match2 match3]
^^^ ^^
这使得第三场比赛可选。
我也将你贪婪的.*
变成了非贪婪的.*?
。
要获得所有匹配,您可以使用更像这样的内容:
if {[string range $line 0 0] ne "#"} {
set matches [regexp -all -inline -- {\d/\d/\d/\d{1,2}(?==p1)} $line]
}
您将获得列表$matches
中的匹配项。然后,您可以通过lindex
或lassign
访问它们,并为其指定具体名称。
答案 1 :(得分:1)
这可能会更好:
lassign [regexp -all -inline {\d+(?:/\d+){3}(?==p1)} $line] var1 var2 var3
如果只有2个匹配,则var3将为空
如果有更多匹配,则只会在变量中捕获前3个。
如果你真的只想要所有的比赛:
set vars [regexp -all -inline {\d+(?:/\d+){3}(?==p1)} $line]
忽略评论:
while {[gets $fh line] != -1} {
if {[regexp {^\s*#} $line]} continue
# do your other stuff here ...
}
答案 2 :(得分:0)
试试这个:
(^|\s)(\d/\d/\d/\d=p1)
或更紧凑:
(^|\s)((\d/){3}\d=p1)