【问题标题】:Tcl Regexp confusionTcl 正则表达式混淆
【发布时间】:2015-06-09 13:54:46
【问题描述】:

我在 tcl 脚本中有以下代码

$a_list - {Hello1.my.name.is.not.adam.go.away, 
           Hello2.my.name.is.not.adam,
           Hello3.my.name.is.not.adam.leave.me}

foreach a $a_list {if {[regexp adam [regsub {.*\.} $a {}]] == 1} {puts $a} }

我的理解是,这会在 $a_list 中查找字符串 adam,并且当 adam 是最后一个字符串时匹配。 例如

Hello1.my.name.is.not.adam.go.away  ---> NO MATCH
Hello2.my.name.is.not.adam          ---> MATCH
Hello3.my.name.is.not.adam.leave.me ---> NO MATCH

我面临的问题是我想与 adam 匹配,然后在包括 adam 本身之后剥离所有内容。 例如

Hello1.my.name.is.not.adam.go.away  ---> MATCH
Hello2.my.name.is.not.adam          ---> MATCH
Hello3.my.name.is.not.adam.leave.me ---> MATCH

在上述所有情况下,它都应该将字符串更改为

Hello1.my.name.is.not  ---> MATCH
Hello2.my.name.is.not  ---> MATCH
Hello3.my.name.is.not  ---> MATCH

感谢您的帮助。 谢谢

【问题讨论】:

    标签: regex tcl


    【解决方案1】:

    方法一:

    通过简单的string 命令,我们就能得到想要的结果。

    set input {Hello1.my.name.is.not.adam.go.away, Hello2.my.name.is.not.adam, Hello3.my.name.is.not.adam.leave.me noobuntu dinesh}
    foreach elem $input {
        # Getting the index of the word 'adam' in each element 
        set idx [string first "adam" $elem]
        # If the word is not  available, then 'idx' will have the value as '-1'
        if {$idx!=-1} {
            # string range will give the substring for the given indices
            puts "->[string range $elem 0 [expr {$idx-1}]]"
        }
    }
    

    会给出如下输出,

    ->Hello1.my.name.is.not.
    ->Hello2.my.name.is.not.
    ->Hello3.my.name.is.not.
    

    方法二:

    如果您只对正则表达式模式感兴趣,那么可以通过regsub 命令将其调整为

    set input {Hello1.my.name.is.not.adam.go.away, Hello2.my.name.is.not.adam, Hello3.my.name.is.not.adam.leave.me noobuntu dinesh}
    foreach elem $input {
        if {[regsub {(.*?)adam.*$} $elem {\1} result]} {
            puts "->$result"
        }
    }
    

    将产生输出为

    ->Hello1.my.name.is.not.
    ->Hello2.my.name.is.not.
    ->Hello3.my.name.is.not.
    

    参考:string,regsub

    【讨论】:

    • regsub {adam.*} $elem {} result 应该更简单 IMO。
    【解决方案2】:

    在列表的每个元素中去除单词adam 及其后的所有内容的最简单方法是使用简单的regsub 和lmap:

    % lmap s $a_list {regsub {\madam\M.*} $s ""}
    Hello1.my.name.is.not. Hello2.my.name.is.not. Hello3.my.name.is.not.
    

    \m 只匹配单词的开头,\M 只匹配单词的结尾。它之所以有效,是因为如果那里没有 这个词,regsub 什么也不做。


    使用 Tcl 8.5?您不会拥有lmap,而是需要这样做:

    set result {}
    foreach s $a_list {
        lappend result [regsub {\madam\M.*} $s ""]
    }
    # The altered list is now in $result
    

    【讨论】:

      猜你喜欢
      • 2023-03-08
      • 2018-07-05
      • 1970-01-01
      • 2012-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-03
      相关资源
      最近更新 更多