tcl:从字符串中获取数字的最简单方法?

tcl : the simplest way to grab number from string?

嗨,假设我有几个名字:orange12 , blue124 , red909 ,我想获取索引号,在这种情况下:12、124 和 909。通常,我可以使用 'string range first last' 来提取子字符串。为了获得第一个和最后一个,我将使用 'string len orange'和 'string len orange12'。现在我正在寻找另一种方法。

作为比较,在 python 中,我可以做类似的事情:

'orange12'.split('orange')[1]
'blue124'.split('blue')[1]
'red909'.split('red')[1]

我怎样才能在 tcl 中做类似的事情?我在 tcl 中尝试了 'split' ,但看起来很复杂并且无法正常工作。在 tcl 中,我如何按单词(不是字符)拆分?

谢谢

这完全取决于您期望的字符串格式。

如果它是一个已知单词(没有数字),例如'orange',后面是一些数字,你可以去掉这个词:

% string map {orange ""} orange12
12
% string map {blue ""} blue124
124
% string map {red ""} red909
909

如果只知道是单词后面跟数字,可以试试正则表达式

% regexp {\d+} orange12 index
1
% puts $index
12

无论如何,请注意数字仍然表示为字符串。如果它以零开头,当转换为数字格式时,它将被解释为八进制,这可能会导致意外结果。

一个选项是通过 scan:

% regexp {\d+} orange012 index
1
% puts $index
012
% expr 1*$index
10
% set index [scan $index %d]
12
% expr 1*$index
12

编辑:采纳了 Peter 的建议之一

有时候,scan 是最有用的工具。它也经常被忽视:

scan "green012" {%[a-z]%d} word num
# $word is now “green”
# $num is now “12”

其他答案向您展示了在 Tcl 中解决问题的最佳方法,但为了回答您提出的问题,这里是 Tcl 中的等效代码:

package require textutil

lindex [textutil::splitx orange12 orange] 1
lindex [textutil::splitx blue124 blue] 1
lindex [textutil::splitx red909 red] 1

textutil 包是 Tcllib 的一部分,Tcl 配套库。 splitx 命令是核心命令 split 的扩展替换:splitx 采用正则表达式而不是字符集来确定在何处拆分字符串参数。

文档:lindex, textutil

我终于找到了我自己问题的最佳答案,我想在这里分享:

set name orange12345
[scan $name [scan $name {%[a-zA-Z]}]%d ] 
#12345

无需知道 'orange12' 中的 'orange' 这个词,我就可以做到这一点。所以源名称可以是任何随机名称,格式如下:ANYNAMEanynumber。例如,像“mywonderfulworld2345612”这样的名称。