Tcl 正则表达式混淆
Tcl Regexp confusion
我在 tcl 脚本中有以下代码
$a_list - {Hello1.my.name.is.not.adam.go.away,
Hello2.my.name.is.not.adam,
Hello3.my.name.is.not.adam.leave.me}
foreach a $a_list {if {[regexp adam [regsub {.*\.} $a {}]] == 1} {puts $a} }
我的理解是,这会在 $a_list 中查找字符串 adam,并且当 adam 是最后一个字符串时它会匹配。
例如
Hello1.my.name.is.not.adam.go.away ---> NO MATCH
Hello2.my.name.is.not.adam ---> MATCH
Hello3.my.name.is.not.adam.leave.me ---> NO MATCH
我面临的问题是我想匹配adam,然后在包括adam 本身之后剥离所有内容。
例如
Hello1.my.name.is.not.adam.go.away ---> MATCH
Hello2.my.name.is.not.adam ---> MATCH
Hello3.my.name.is.not.adam.leave.me ---> MATCH
在上述所有情况下,应将字符串更改为
Hello1.my.name.is.not ---> MATCH
Hello2.my.name.is.not ---> MATCH
Hello3.my.name.is.not ---> MATCH
感谢您的帮助。
谢谢
方法一:
通过简单的string
命令,我们可以得到想要的结果。
set input {Hello1.my.name.is.not.adam.go.away, Hello2.my.name.is.not.adam, Hello3.my.name.is.not.adam.leave.me noobuntu dinesh}
foreach elem $input {
# Getting the index of the word 'adam' in each element
set idx [string first "adam" $elem]
# If the word is not available, then 'idx' will have the value as '-1'
if {$idx!=-1} {
# string range will give the substring for the given indices
puts "->[string range $elem 0 [expr {$idx-1}]]"
}
}
会给出如下输出,
->Hello1.my.name.is.not.
->Hello2.my.name.is.not.
->Hello3.my.name.is.not.
方法二:
如果您只对正则表达式模式感兴趣,那么可以通过 regsub
命令将其调整为
set input {Hello1.my.name.is.not.adam.go.away, Hello2.my.name.is.not.adam, Hello3.my.name.is.not.adam.leave.me noobuntu dinesh}
foreach elem $input {
if {[regsub {(.*?)adam.*$} $elem {} result]} {
puts "->$result"
}
}
将产生输出
->Hello1.my.name.is.not.
->Hello2.my.name.is.not.
->Hello3.my.name.is.not.
在列表的每个元素中去除单词 adam
及其后所有内容的最简单方法是使用简单的 regsub
和 lmap
:
% lmap s $a_list {regsub {\madam\M.*} $s ""}
Hello1.my.name.is.not. Hello2.my.name.is.not. Hello3.my.name.is.not.
\m
只匹配词首,\M
只匹配词尾。之所以有效,是因为如果 不存在 ,regsub
就什么都不做。
使用 Tcl 8.5?您不会有 lmap
,而是需要这样做:
set result {}
foreach s $a_list {
lappend result [regsub {\madam\M.*} $s ""]
}
# The altered list is now in $result
我在 tcl 脚本中有以下代码
$a_list - {Hello1.my.name.is.not.adam.go.away,
Hello2.my.name.is.not.adam,
Hello3.my.name.is.not.adam.leave.me}
foreach a $a_list {if {[regexp adam [regsub {.*\.} $a {}]] == 1} {puts $a} }
我的理解是,这会在 $a_list 中查找字符串 adam,并且当 adam 是最后一个字符串时它会匹配。 例如
Hello1.my.name.is.not.adam.go.away ---> NO MATCH
Hello2.my.name.is.not.adam ---> MATCH
Hello3.my.name.is.not.adam.leave.me ---> NO MATCH
我面临的问题是我想匹配adam,然后在包括adam 本身之后剥离所有内容。 例如
Hello1.my.name.is.not.adam.go.away ---> MATCH
Hello2.my.name.is.not.adam ---> MATCH
Hello3.my.name.is.not.adam.leave.me ---> MATCH
在上述所有情况下,应将字符串更改为
Hello1.my.name.is.not ---> MATCH
Hello2.my.name.is.not ---> MATCH
Hello3.my.name.is.not ---> MATCH
感谢您的帮助。 谢谢
方法一:
通过简单的string
命令,我们可以得到想要的结果。
set input {Hello1.my.name.is.not.adam.go.away, Hello2.my.name.is.not.adam, Hello3.my.name.is.not.adam.leave.me noobuntu dinesh}
foreach elem $input {
# Getting the index of the word 'adam' in each element
set idx [string first "adam" $elem]
# If the word is not available, then 'idx' will have the value as '-1'
if {$idx!=-1} {
# string range will give the substring for the given indices
puts "->[string range $elem 0 [expr {$idx-1}]]"
}
}
会给出如下输出,
->Hello1.my.name.is.not.
->Hello2.my.name.is.not.
->Hello3.my.name.is.not.
方法二:
如果您只对正则表达式模式感兴趣,那么可以通过 regsub
命令将其调整为
set input {Hello1.my.name.is.not.adam.go.away, Hello2.my.name.is.not.adam, Hello3.my.name.is.not.adam.leave.me noobuntu dinesh}
foreach elem $input {
if {[regsub {(.*?)adam.*$} $elem {} result]} {
puts "->$result"
}
}
将产生输出
->Hello1.my.name.is.not.
->Hello2.my.name.is.not.
->Hello3.my.name.is.not.
在列表的每个元素中去除单词 adam
及其后所有内容的最简单方法是使用简单的 regsub
和 lmap
:
% lmap s $a_list {regsub {\madam\M.*} $s ""}
Hello1.my.name.is.not. Hello2.my.name.is.not. Hello3.my.name.is.not.
\m
只匹配词首,\M
只匹配词尾。之所以有效,是因为如果 不存在 ,regsub
就什么都不做。
使用 Tcl 8.5?您不会有 lmap
,而是需要这样做:
set result {}
foreach s $a_list {
lappend result [regsub {\madam\M.*} $s ""]
}
# The altered list is now in $result