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
采用正则表达式而不是字符集来确定在何处拆分字符串参数。
我终于找到了我自己问题的最佳答案,我想在这里分享:
set name orange12345
[scan $name [scan $name {%[a-zA-Z]}]%d ]
#12345
无需知道 'orange12' 中的 'orange' 这个词,我就可以做到这一点。所以源名称可以是任何随机名称,格式如下:ANYNAMEanynumber。例如,像“mywonderfulworld2345612”这样的名称。
嗨,假设我有几个名字: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
采用正则表达式而不是字符集来确定在何处拆分字符串参数。
我终于找到了我自己问题的最佳答案,我想在这里分享:
set name orange12345
[scan $name [scan $name {%[a-zA-Z]}]%d ]
#12345
无需知道 'orange12' 中的 'orange' 这个词,我就可以做到这一点。所以源名称可以是任何随机名称,格式如下:ANYNAMEanynumber。例如,像“mywonderfulworld2345612”这样的名称。