【问题标题】:tcl : the simplest way to grab number from string?tcl:从字符串中获取数字的最简单方法?
【发布时间】:2016-03-26 19:16:59
【问题描述】:

嗨,假设我有几个名字:orange12 , blue124 , red909 ,并且我想获取索引号,在这种情况下:12、124 和 909。通常,我可以使用“字符串范围第一个最后一个”来提取子字符串。要获取第一个和最后一个,我将使用“字符串 len 橙色” ' 和 'string len orange12'。现在我正在寻找另一种方法。

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

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

我怎样才能在 tcl 中做类似的事情?我在 tcl 中尝试了“拆分”,但似乎很复杂,无法使其工作。在 tcl 中,我如何用一个单词(不是字符)来分割?

谢谢

【问题讨论】:

    标签: string split tcl extract


    【解决方案1】:

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

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

    【讨论】:

    • 我忽略了它。是的...这比我的正则表达式回复更好
    • 这很酷。但我有更多的问题:如果我需要它“扫描”来返回 word 或 num 的值,而不必将其存储到“word”和“num”变量中。我需要将它用作我的 python 脚本中的在线函数。例如,我想将名称从“orange12”更改为“newname12”。我希望做类似的事情: newname[scan "orange12" {%d} ] ,所以输出应该是:newname12。现在“扫描”命令将返回匹配数
    • @andio:试试set name newname[lindex [scan "orange12" {%[a-z]%d}] 1],或者更好的set name [string map {orange newname} "orange12"]
    • @Peter:谢谢...所有脚本都很好用:-)。
    • @Donal:感谢您的启发...从您的脚本中,我终于提取了这样的内容:newname[scan $name [scan $name {%[a-zA-Z]}]%d ] 。我可以做到这一点而不必知道“orange12”中的“橙色”这个词。因此源名称可以是任何随机名称,格式如下:ANYNAMEanynumber。例如,像“mywonderfulworld2345612”这样的名称。感谢 guyz 的帮助和所有这些脚本。
    【解决方案2】:

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

    如果它是一个已知单词(没有数字),例如'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
    

    编辑:使用了彼得的建议之一

    【讨论】:

    • 考虑regexp 变体regexp -inline {\d+} orange12(将数字作为返回值)或regexp {\d+} orange12 index(更简单一点)。
    【解决方案3】:

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

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

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

    文档:lindextextutil

    【讨论】:

    • PS:除了其他方法之外,还可以使用string trimleft $s abdeglnoru 之类的方法(其中s 包含颜色数字字符串),但这实际上很愚蠢。 ;)
    【解决方案4】:

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

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

    我可以做到这一点,而不必知道 'orange12' 中的 'orange' 这个词。因此源名称可以是任意随机名称,格式如下:ANYNAMEanynumber。例如,像“mywonderfulworld2345612”这样的名称。

    【讨论】:

    • 请注意,上面的几个解决方案同样不需要知道单词是什么。如果此解决方案试图避免从 scan 命令获取两个值,则可以使用 scan $name {%*[a-zA-Z]%d} 更简单地完成此操作,它只返回数值,而不管单词是什么。
    猜你喜欢
    • 2016-06-22
    • 2011-06-08
    • 2019-03-12
    • 2018-07-09
    • 1970-01-01
    • 2016-07-15
    • 1970-01-01
    • 2011-09-19
    • 2010-11-06
    相关资源
    最近更新 更多