如何使用正则表达式匹配字符串中的第 n 次出现

vel*_*ian 5 regex tcl regex-greedy

如何使用正则表达式匹配字符串中的第 n 次出现

set test {stackoverflowa 是查找站点的最佳解决方案 stackoverflowb 是查找站点的最佳解决方案 stackoverflowc 是查找站点的最佳解决方案stackoverflowd 是查找站点的最佳解决方案stackoverflowe 是查找站点的最佳解决方案}

regexp -all {stackoverflow} $test 
Run Code Online (Sandbox Code Playgroud)

上面的一个给出“5”作为输出

regexp {stackoverflow} $test 
Run Code Online (Sandbox Code Playgroud)

上面的结果给出了stackoverflow,这里它匹配stackoverflow的第一次出现(即)stackoverflowa

我的要求是我想从上面给定的字符串中匹配第 5 次出现的 stackoverflow(即)stackoverflowe。

请有人澄清我的问题..谢谢

然后又一个问题

Pet*_*rin 3

尝试

set results [regexp -inline -all {stackoverflow.} $test]
# => stackoverflowa stackoverflowb stackoverflowc stackoverflowd stackoverflowe
puts [lindex $results 4]
Run Code Online (Sandbox Code Playgroud)

我很快就会回来进一步解释这一点,现在就做煎饼。

所以。

该命令返回与字符串“stackoverflow”(少引号)匹配的字符串中包含的-inline所有 ( ) 个子字符串的列表( ) 加一个字符,该字符可以是任何字符。该列表存储在变量 中,并且通过使用 4 进行索引(因为索引是从零开始的),可以检索该列表的第五个元素(并且在本例中打印)。-alltestresult

表达式末尾的点不在您的表达式中:我添加它是为了检查我是否确实获得了正确的匹配。您当然可以省略点以完全匹配“stackoverflow”。

ETA(来自 Donal 的评论):在许多情况下,提取字符串本身而不是提取它在搜索字符串中的位置和范围是很方便的。该-indices选项为您提供了这一点(我现在不在表达式中使用点:索引列表使我清楚地知道我得到的是哪一个“stackoverflow”):

set indices [regexp -inline -all -indices {stackoverflow} $test]
# => {0 12} {47 59} {94 106} {140 152} {186 198}
Run Code Online (Sandbox Code Playgroud)

然后您可以使用string range来获取字符串匹配:

puts [string range $test {*}[lindex $indices 4]]
Run Code Online (Sandbox Code Playgroud)

他们lindex $indices 4给了我清单186 198;前缀{*}使该列表中的两个元素在 的调用中显示为两个单独的参数string range