【问题标题】:Tcl string compare and replace with asteriskTcl 字符串比较并用星号替换
【发布时间】:2022-01-14 12:06:36
【问题描述】:

我想在 TCL 中比较两个字符串,并将不匹配的字符替换为星号。

Core_cpuss_5/loop2/hex_reg[89]cpu_ip[45]_reg10/D[23] Core_cpuss_5/loop2/hex_reg[56]cpu_ip[12]_reg5/D[33]

需要输出:Core_cpuss_5/loop2/hex_reg[ * ]cpu_ip[ * ]_reg*/D[*]

我在上面尝试使用 regsub,但没有按预期工作。

foreach v {string1 string2} {
regsub {\[[0-9]+\]$} $v {[*]} v_modified
}

【问题讨论】:

    标签: string tcl string-matching regexp-replace regsub


    【解决方案1】:

    用 * 替换方括号内的整数(并将 reg10 和 reg5 更改为 reg*)

    set string1 {Core_cpuss_5/loop2/hex_reg[89]cpu_ip[45]_reg10/D[23]}
    set string2 {Core_cpuss_5/loop2/hex_reg[56]cpu_ip[12]_reg5/D[33]}
    foreach v "$string1 $string2" {
        regsub -all {\[\d+\]} $v {[*]} v_modified
        regsub -all {reg\d+} $v_modified {reg*} v_modified
        puts $v_modified
    }
    

    我修复了您的代码中的几个问题:

    1. {string1 string2} 更改为"$string1 $string2"
    2. -all 添加到regexp 命令查找所有匹配项。
    3. 从正则表达式中删除$,因为它只匹配最后一个。
    4. 添加另一个regsub 将reg10 和reg5 更改为reg*。

    如果您需要更通用的解决方案,这将在每个字符串中找到一个整数序列,如果它们不同,则用 * 替换:

    set string1 {Core_cpuss_5/loop2/hex_reg[89]cpu_ip[45]_reg10/D[23]}
    set string2 {Core_cpuss_5/loop2/hex_reg[56]cpu_ip[12]_reg5/D[33]}
    
    # Initialize start positions for regexp for each string.
    set start1 0
    set start2 0
    
    # Incrementally search for integers in each string.
    while {1} {
        # Find a match for an integer in each string and save the {begin end} indices of the match
        set matched1 [regexp -start $start1 -indices {\d+} $string1 indices1]
        set matched2 [regexp -start $start2 -indices {\d+} $string2 indices2]
    
        if {$matched1 && $matched2} {
            # Use the indices to get the matched integer
            set value1 [string range $string1 {*}$indices1]
            set value2 [string range $string2 {*}$indices2]
    
            # Replace the integer with *
            if {$value1 ne $value2} {
                set string1 [string replace $string1 {*}$indices1 "*"]
                set string2 [string replace $string2 {*}$indices2 "*"]
            }
        } else {
            break
        }
    
        # Increment the start of the next iteration.
        set start1 [expr {[lindex $indices1 1]+1}]
        set start2 [expr {[lindex $indices2 1]+1}]
    }
    
    puts "String1 : $string1"
    puts "String2 : $string2"
    

    上面的方法只有在两个字符串足够相似的情况下才有效(就像它们每个都有相同数量的整数以相似的顺序)

    【讨论】:

    • 更好: 1. 将{string1 string2} 更改为[list $string1 $string2]。当有空格或其他字符会混淆任一字符串中的列表解析时,这将继续有效。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-27
    • 2018-12-07
    • 1970-01-01
    • 2015-02-25
    • 2021-12-20
    相关资源
    最近更新 更多