计算 Tcl 8.0 上子字符串的出现次数

Counting occurrences of a substring on Tcl 8.0

我想弄清楚一个字符串在另一个字符串中出现了多少次,Tcl 似乎没有内置。我不能在 wiki 上使用任何一种解决方案,因为我必须支持 Tcl 8.0。

这不起作用:

# needleString is known to contain no regex metacharacters
llength [regexp -all -inline $needleString $haystackString]

因为 8.0 不支持 -all

这不起作用:

proc string_occurrences {needleString haystackString} {

    set j [string first $needleString $haystackString 0]
    if {$j == -1} {return 0}

    set i 0
    while {$j != -1 } {
        set j [string first $needleString $haystackString [incr j]]
        incr i
    }

    return $i
}

因为 string first 不支持 8.0 上的 startIndex 参数。

我可以修改 string_occurrences 以使用 string range 获取字符串的子字符串和 2-argument string first 在其中搜索,但这比循环更麻烦,我不知道 string range 的效率如何。我有更好的选择吗?

您可以使用 [regsub -all](在 8.0 中存在)创建一个删除了 needleString 的新字符串,并比较长度:

proc string_occurrences {needleString haystackString} {
    regsub -all $needleString $haystackString {} stripped
    expr {([string length $haystackString] - [string length $stripped]) / [string length $needleString]}
}