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

5

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

设置测试字符串为 {stackoverflowa 是一个最佳的解决方案查找网站 stackoverflowb 是一个最佳的解决方案查找网站 stackoverflowc 是一个 最佳的解决方案查找网站 stackoverflowd 是一个最佳的解决方案查找网站 stackoverflowe 是一个最佳的解决方案查找网站}

regexp -all {stackoverflow} $test 

上面的代码会输出“5”
regexp {stackoverflow} $test 

以上代码会返回stackoverflow的结果,它匹配第一个stackoverflow(即stackoverflowa)。

我的要求是要匹配字符串中的第5个stackoverflow(即stackoverflowe)。

请有经验的人解答我的问题,谢谢。

接下来还有另一个问题。


1
你想匹配包含第5次出现的stackoverflow的整个单词,是吗? - brandonscript
1
第5次出现是最后一次出现。如果它们不是同一个东西,那么您需要类似/(.*?(stackoverflow\S*)){5}/的东西,在捕获组2中回答。不知道tcl是否支持这样的语法。 - user557597
语法是支持的,但结果有点不直观:正确的匹配会被存储在第二个匹配变量中。 - Peter Lewerin
@sln:为了完整和清晰起见,调用是 regexp {(.*?(stackoverflow\S*)){5}} $test m sm ssm。这将把“stackoverflow”的第五个出现(省略“e”)放入子子匹配变量(调用中的ssm)中。 - Peter Lewerin
1个回答

3

尝试

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

我将很快回来进一步解释这个问题,现在正在煎薄饼。

所以。

该命令返回一个列表(-inline),其中包含test中包含"stackoverflow"(不带引号)加上一个任意字符的所有(-all)子字符串。此列表存储在变量result中,并通过使用索引4(因为索引是从0开始的)来检索该列表的第五个元素(并且,在这种情况下,打印它)。

表达式末尾的点号不在您的表达式中:我添加它以检查是否确实得到了正确的匹配。 当然,您可以省略点来精确匹配"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时,前缀{*}会将该列表中的两个元素作为两个单独的参数呈现。


你会得到整个匹配的循环结果(其中之一是 stackoverflowa ... stackoverflowe),然后是第一个子匹配项(在每种情况下都是 stackoverflow),接着是四个子子匹配项(tacoverflow),最后在每个循环中都有一个(a ... e)(第二个子匹配项)。 - Peter Lewerin
+1 我错误地认为 OP 真正意思是“最后”,因为你知道,有时候说的话并不是真正的意思 ^^; - Jerry
1
@sln:它返回四个元素:从字符串开头到“...flowe”的大匹配,然后是最后一个子匹配,然后是最后一个子匹配的两个子匹配。但你知道,我不是tclsh:为什么不自己试一下呢? - Peter Lewerin
抱歉,我也不知道,只是想知道它的引擎在这方面是否有价值。显然,到目前为止,只有Dot-Net会将迭代子表达式匹配记录在量化外部组的数组中。这并不是什么大问题,但是,Dot-Net不会进行递归调用,而PCRE样式不会进行中间捕获。这使得有意义的语言解析变得困难。 - user557597
“-indices”选项在实际应用中很有用,但很少产生易读的示例(字符串结果在某种程度上显而易见,而索引对则不是),因此当回答类似于此类问题时,我倾向于不提及它。也许我应该提一下。 - Peter Lewerin
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接