我想通过逗号分隔的字符串,并用更多逗号分隔的元素替换匹配。
即5-A,在regsub之后的B应该给我1-A,2-A,3-A,4-A,5-A,B
以下对我来说不适用于&正在作为一个实际的&而不是实际匹配:
regsub -all {\d+\-\w+} $string [myConvertProc &]
然而,并没有试图通过&直接使用它:
regsub -all o "Hello World" &&&
> Hellooo Wooorld
在尝试传递价值&时,不确定我做错了什么坚持 myConvertProc
编辑: 我认为我最初的问题是[myConvertProc&]首先得到评估,所以我实际上正在传递'&'该程序。
如何在正则表达式领域解决这个问题?有可能吗?
编辑2: 我已经在拆分列表中使用foreach解决了它,所以我只是想在regsub中查看这是否可行。谢谢!
答案 0 :(得分:3)
你的第一次编辑是正确的:问题是在执行命令之前,regsub
的每个参数都被完全评估。
一种解决方案是在字符串中插入命令替换字符串,然后在其上使用subst
:
set string [regsub -all {\d+\-\w+} $string {[myConvertProc &]}]
# -> [myConvertProc 5-A],B
set string [subst $string]
# -> 1-A,2-A,3-A,4-A,5-A,B
只有在string
中没有其他内容可以替换时才会有效(但您当然可以关闭变量和反斜杠替换)。
foreach
解决方案要好得多。另一种foreach
解决方案是迭代regexp -indices -inline -all
的结果,但如果它有效,则迭代分割列表的各个部分是可取的。
<强>更新强>
典型的foreach
解决方案如下:
set res {}
foreach elem [split $string ,] {
if {[regexp -- {^\d+-\w+$} $elem]} {
lappend res [myConvertProc $elem]
} else {
lappend res $elem
}
}
join $res ,
也就是说,通过查看原始列表中的每个元素来收集结果列表。如果元素符合您的要求,则转换它并将结果添加到结果列表中。如果元素不匹配,只需将其添加到结果列表中即可。
在Tcl 8.6中可以稍微简化一下:
join [lmap elem [split $string ,] {
if {[regexp -- {^\d+-\w+$} $elem]} {
myConvertProc $elem
} else {
set elem
}
}] ,
这是一回事,但lmap
命令会为您处理结果列表。