我的字符串如下:
str1.str2.strn-1。{I} .strn
我使用sed
命令删除最后一个点后面的字符串'。'
proc check_str {str} {
set cmd "echo $str | sed -E 's/[^.]+$//'"
set new_str [exec sh -c $cmd]
puts "the new string is :$new_str"
}
但我收到了错误:
命令名称无效^。
并且不显示新字符串!
如何显示新字符串?
答案 0 :(得分:2)
regsub
命令匹配正则表达式并将替换应用于匹配的文本。这与你使用sed的s
非常相似。
set new_str [regsub {[^.]+$} $str ""]
请注意,将正则表达式放在大括号中(在Tcl中非常类似于unix shell中的单引号)几乎总是很重要,因为它们通常包含Tcl元字符。在这种情况下,正则表达式包含[
,]
和$
(尽管处于终端位置);它需要引用或者Tcl将尝试执行奇怪命名的命令^.
它也可能被引用了反斜杠,但这很烦人且不清楚。
这也是你之前尝试提问的错误。使用exec sed
是完全矫枉过正的。使用exec echo … | sed
会更糟糕,就像在sh -c
内部一样。正确的工具即将到来,并且效率更高(假设您已经在Tcl中)。
答案 1 :(得分:1)
我找到了一个使用tcl的解决方案:
regsub -- {[^.]+$} $str {} string
答案 2 :(得分:1)
另一种Tcl技术是将该字符串拆分为单词列表,使用点作为分隔符。用空字符串替换最后一个单词。加入这些话。
set str {str1.str2.strn-1.{i}.strn}
set words [split $str .]
lset words end ""
set new [join $words .] # => str1.str2.strn-1.{i}.
另一种技术是找到字符串中最后一个点的索引。然后将子串从零到该索引
set new [string range $str 0 [string last . $str]]
IMO甚至regsub对此任务都是过度的。
答案 3 :(得分:1)
有一个命令几乎完全符合你的要求,除了它也删除了最后一个点 - 但是通过在末尾添加一个新点很容易解决:
set new [file rootname $str].
# => str1.str2.strn-1.{i}.
文档:file