我试图从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] "." ]"
这给我确切的输出我想要的,但我想知道如果在Tcl的做到这一点任何其他有效的方式。
你可以使用分割为下划线分隔该文件名,然后再加入第一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
编辑
所以,如果“名”可以有下划线的任意数:
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
但是,这是越来越复杂。 一个正则表达式应该足够了 - 我认为“串”可非强调字符的任何序列。
set string {[^_]+}
set regex "^(.+)_($string)_10a.${string}_10a.$string.$string.$string\$"
regexp $regex $f -> name ext
set out "$name.$ext" ;#==> foo_bar_baz.ext
做提取的一种方法是用regsub
:
regsub {^([^_]+)_([^_]+)_.*} $_File {\1.\2} _File
正则表达式中包含([^_]+)
组分,匹配的非下划线字符的序列,以及一个锚定件和一些下划线,和后非捕获哪个.*
相匹配一切(因此我们可以将其丢弃)。 所述regsub
替换(其是整个字符串)与具有两个匹配的非下划线部分的级联.
之间,并回到它写入_File
其中字符串是从哪里来的变量。
请注意,我把括号正则表达式和更换。 这是因为它们含有我要Tcl的通入的Tcl元字符(方括号和反斜线) regsub
一字不差。