如何在tcl中执行子串提取和替换

Pun*_*tal 3 string tcl

我试图从Tcl中的字符串中提取子字符串.我编写了代码并且能够做到,但我想知道是否还有其他有效的方法可以做到这一点.所以确切的问题是我有一个字符串

name_ext_10a.string_10a.string.string.string

我想提取" name_ext",然后删除" _"并将其替换为" ."; 我终于希望输出为" name.ext".我写了这样的东西:

set _File "[string replace $_File [string last "_" $_File] [string length $_File] "" ]"
set _File "[string replace $_File [string last "_" $_File] [string length $_File] "" ]"
set _File "[string replace $_File [string last "_" $_File] [string last "_" $_File] "." ]"
Run Code Online (Sandbox Code Playgroud)

这给了我想要的确切输出,但我想知道在Tcl中是否还有其他有效的方法可以做到这一点.

gle*_*man 5

您可以使用下划线作为分隔符来拆分该文件名,然后使用点连接前2个元素:

% set f name_ext_10a.string_10a.string.string.string
name_ext_10a.string_10a.string.string.string
% set out [join [lrange [split $f _] 0 1] .]
name.ext
Run Code Online (Sandbox Code Playgroud)

编辑

因此,如果"name"可以有任意数量的下划线:

set f "foo_bar_baz_ext_10a.string_10a.string.string.string"
set pieces [split $f _]
set name [join [lrange $pieces 0 end-3] _]
set out [join [list $name [lindex $pieces end-2]] .]  ;#==> foo_bar_baz.ext
Run Code Online (Sandbox Code Playgroud)

但这变得越来越复杂.一个正则表达式应该足够 - 我假设"字符串"可以是任何非下划线字符序列.

set string {[^_]+}
set regex "^(.+)_($string)_10a.${string}_10a.$string.$string.$string\$"
regexp $regex $f -> name ext
set out "$name.$ext"    ;#==> foo_bar_baz.ext
Run Code Online (Sandbox Code Playgroud)