如何将 tcl 字符串与中间的无关字符进行比较?

How to compare tcl strings with don't care chars in the middle?

我有要比较的字符串列表
比较 2 个字符串时,我想忽略一个字符 - 使其成为无关紧要的字符。
例如
Mister_T_had4_beers
应该等于:
Mister_Q_had4_beers
但不应等于 Mister_T_had2_beers
我知道 _had\d+ 会一直出现在字符串中,所以可以用作锚点。

我相信我可以使用正则表达式拆分 2 个字符串并进行比较,或者使用 string equal -length 切中要点,但必须有更好的方法...

编辑
基于下面的答案(必须阅读 - 纯金!)解决方案来自正则表达式:
regexp -line {(.*).(_had\d+.*)\n.$} $str1\n$str2

如果您知道哪个字符可以变化,最简单的方法是在变化的位置使用 string match?

if {[string match Mister_?_had4_beers $string1]} {
    puts "$string1 matches the pattern"
}

您还可以使用 string rangestring replace 来获取要比较的字符串:

# Compare substrings; prefixes can be done with [string equal -length] too
if {[string range $string1 0 6] eq [string range $string2 0 6]
        && [string range $string1 8 end] eq [string range $string2 8 end]} {
     puts "$string1 and $string2 are equal after ignoring the chars at index 7"
}
# Compare strings with variation point removed
if {[string replace $string1 7 7] eq [string replace $string2 7 7]} {
     puts "$string1 and $string2 are equal after ignoring the chars at index 7"
}

让变化点处于任意位置比较棘手。最简单的方法是 select 一个出现在 两个 字符串中的字符,比如说一个换行符,然后用它来制作一个我们可以 运行 更详尽的 RE 反对:

regexp -line {^(.*).(.*)\n.$} $string1\n$string2

使用换行的好处是regexp-line匹配方式使得.匹配换行;我们需要明确地匹配它(这对我们的目的很有帮助)。

如果您要比较的字符串中有换行符,您将需要选择其他内容(并且首选 RE 变得更冗长)。您可以选择许多罕见的 Unicode 字符,但 \u0000 (NUL) 是最好的字符之一,因为它在非二进制数据中非常罕见。