如何使用正则表达式匹配字符串中的第n个匹配项

时间:2014-01-23 17:32:14

标签: regex tcl regex-greedy

如何使用正则表达式匹配字符串中的第n个匹配项

  

set test {stackoverflowa是寻找网站的最佳解决方案   stackoverflowb是寻找站点stackoverflowc的最佳解决方案   找到sitestackoverflowd的最佳解决方案是最佳解决方案   sitestackoverflowe是寻找网站的最佳解决方案}

regexp -all {stackoverflow} $test 

以上提供“5”作为输出

regexp {stackoverflow} $test 

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

我的要求是我希望匹配来自上面给定字符串的stackoverflow(即)stackoverflowe的第5次出现

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

然后另一个问题

1 个答案:

答案 0 :(得分:3)

尝试

set results [regexp -inline -all {stackoverflow.} $test]
# => stackoverflowa stackoverflowb stackoverflowc stackoverflowd stackoverflowe
puts [lindex $results 4]

我很快就会回来解释这个问题,现在制作煎饼。

所以

该命令返回-inline中包含的字符串的所有(-all)子串的列表(test),该字符串匹配字符串“stackoverflow”(更少的引号)加上一个字符,可以是任何角色。此列表存储在变量result中,并通过索引4(因为索引从零开始),可以检索此列表的第五个元素(在这种情况下,打印)。

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

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

set indices [regexp -inline -all -indices {stackoverflow} $test]
# => {0 12} {47 59} {94 106} {140 152} {186 198}

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

puts [string range $test {*}[lindex $indices 4]]

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