如何使用正则表达式匹配字符串中的第n个匹配项
set test {stackoverflowa是寻找网站的最佳解决方案 stackoverflowb是寻找站点stackoverflowc的最佳解决方案 找到sitestackoverflowd的最佳解决方案是最佳解决方案 sitestackoverflowe是寻找网站的最佳解决方案}
regexp -all {stackoverflow} $test
以上提供“5”作为输出
regexp {stackoverflow} $test
上面给出了stackoverflow作为结果,这里匹配第一次出现的 stackoverflow (即)stackoverflowa
我的要求是我希望匹配来自上面给定字符串的stackoverflow(即)stackoverflowe的第5次出现。
请有人澄清我的问题。谢谢
然后另一个问题
答案 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
的调用中显示为两个单独的参数。