我想获得字符串中重复特定数字的次数? 考虑数字是2,如果22在sting中可用,我们不应该考虑重复数字。
set a "1232163122631261112312"
在那个2中重复5次(我们不应该把22重复2次重复2次),我想通过使用正则表达式得到这个信息。
答案 0 :(得分:1)
在循环中逐个字符扫描字符串可能会更快,但如果你坚持使用正则表达式:
对于数字2+
的特定示例,您应使用的正则表达式为2
(=数字1+
的一倍或多倍)。然后你可以计算一个循环中的匹配数。
如果您希望其他数字相同,请复制该流程(使用3+
,{{1}}等...)
答案 1 :(得分:1)
最紧凑的方式可能是:
string length [regsub -all {[^2]+|2{2,}} $a {}]
但还有更多内容。
测量列表中项目的频率非常简单:
set freq {}
foreach item $list {dict incr freq $item}
生成的字典将包含键及其频率的项目作为值。
如果您只想知道字符串中有多少'2',您可以使用该方法(split $a {}
将字符串a转换为其组成字符列表):
set freq {}
foreach item [split $a {}] {dict incr freq $item}
dict get $freq 2
但是在这种情况下不起作用,因为你需要取消两个或更多相邻'2'的出现。解决这个问题的一种方法是在测量频率之前删除有问题的事件:
set freq {}
set b [regsub -all {2{2,}} $a {}]
foreach item [split $b {}] {dict incr freq $item}
dict get $freq 2
另一种方法是抛弃任何不是你想要的东西,然后计算你剩下的东西。在这种情况下,您不寻找的是1)不是'2'([^2]+
)的连续数字组,以及2)多个连续数字的组 '2'(2{2,}
),导致正则表达式[^2]+|2{2,}
:
set b [regsub -all {[^2]+|2{2,}} $a {}]
string length $b
您也可以让regexp
命令将字符串拆分为'2'组,然后使用拒绝过滤操作取出多个数字的组(可以方便地将其视为大于由一个数字组成的整数):
set b [regexp -inline -all {2+} $a]
# -> 2 2 22 2 2 2
set c [lmap item $b {if {$item > 2} continue {set item}}]
# -> 2 2 2 2 2
llength $c
# -> 5
或两个嵌套regexp
s,外部删除所有包含多个字符的单词:
set b [regexp -inline -all {\m.\M} [regexp -inline -all {2+} $a]]
# -> 2 2 2 2 2
llength $b
# -> 5
或者您可以使用一些其他方法组合,可能折叠成单个命令而不是连续命令,其中保持变量将一个命令的结果传递给下一个命令:
llength [lmap item [regsub -all {[^2]+} $a { }] {if {$item > 2} continue {set item}}]
这个用空格替换所有不是'2'的数字,留下一个字符串,该字符串也是一个或多个'2'的组的列表。然后,该列表将通过上面的拒绝过滤器传递。
或者这个怎么样:
set b [regsub -all {[^2]+|2{2,}} $a 0]
set c [string map {2 1} $b]
expr [join [split $c {}] +]
# or
::tcl::mathop::+ {*}[split $c {}]
通过将违规组替换为0,然后将'2'替换为1,然后将字符串拆分为列表并在每个数字之间重新加入+字符,并将它们与expr
相加,或者通过传递通过将$c
拆分为::tcl::mathop::+
命令获得的列表中的每个项目。
文档:continue,dict,foreach,if,join,llength,lmap,{{3 }},mathop,regexp,regsub,set,split
答案 2 :(得分:0)