如何在Tcl中使用regsub/regex处理字符串:去首尾与提取子串
嘿,我来帮你搞定这两个Tcl正则的问题,都是日常处理字符串很实用的场景,咱直接上代码和清晰的解释:
问题1:去除字符串的首尾字符(针对你说的“start”时段字符串)
我先假设你是指去掉某个字符串的首尾各一个字符(不管首尾是什么字符),或者如果是要去掉被start标记包裹的首尾标识,我都给你对应的方案:
场景A:去掉任意字符串的首尾单个字符
比如把"abc123"变成"bc12",用regsub一行就能搞定:
set my_str "abc123" regsub {^.(.*).$} $my_str {\1} trimmed_str puts $trimmed_str ;# 输出 bc12
正则解释:
^:匹配字符串的开头.:匹配首尾的任意单个字符(第一个.对应开头字符,最后一个.对应结尾字符)(.*):捕获中间所有内容,存到分组1中$:匹配字符串的结尾{\1}:替换成捕获到的分组1内容,也就是中间部分
如果用regexp提取中间内容也可以:
set my_str "abc123" if {[regexp {^.(.*).$} $my_str -> middle]} { puts $middle ;# 输出 bc12 }
场景B:去掉首尾的start标识(比如字符串是"startHelloWorldstart")
如果你的“start时段”是指字符串首尾有start前缀后缀,要去掉它们保留中间内容:
set my_str "startHelloWorldstart" regsub {^start(.*)start$} $my_str {\1} trimmed_str puts $trimmed_str ;# 输出 HelloWorld
这个正则的逻辑是精准匹配首尾的start,捕获中间的所有内容并替换回去。
问题2:提取两个@之间的内容并删除其余部分
针对你给的行learning lesson number@12.4.1@_01.html,我们可以用regexp直接捕获目标内容,或者用regsub替换掉无关内容,两种方案都很简单:
方案1:用regexp捕获目标
set line "learning lesson number@12.4.1@_01.html" if {[regexp {@([^@]+)@} $line -> target]} { puts $target ;# 输出 12.4.1 }
正则解释:
@:匹配第一个@符号([^@]+):捕获除了@之外的所有字符([^@]是否定字符集,+表示至少一个),这样能精准匹配两个@之间的内容,不会误匹配多个@的情况@:匹配第二个@符号
方案2:用regsub替换成目标内容
set line "learning lesson number@12.4.1@_01.html" regsub {.*@([^@]+)@.*} $line {\1} result puts $result ;# 输出 12.4.1
正则解释:
.*@:匹配第一个@之前的所有内容(.*是贪婪匹配,会一直匹配到第一个@的位置)([^@]+):同样捕获两个@之间的目标内容@.*:匹配第二个@之后的所有内容- 最后用
{\1}替换整个字符串,就只保留了我们要的部分
内容的提问来源于stack exchange,提问作者Diego Henrique
相关产品推荐
相关产品推荐

