【问题标题】:How to match nth occurrence in a string using regular expression如何使用正则表达式匹配字符串中的第 n 个出现
【发布时间】:2014-02-14 10:14:11
【问题描述】:

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

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

regexp -all {stackoverflow} $test 

上面给出“5”作为输出

regexp {stackoverflow} $test 

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

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

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

还有一个问题

【问题讨论】:

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

标签: regex tcl regex-greedy


【解决方案1】:

试试

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

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

所以。

该命令返回一个列表 (-inline),其中包含 test 中包含的字符串的所有 (-all) 子字符串,这些子字符串与字符串“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 的调用中显示为两个单独的参数。

【讨论】:

  • 我知道,对吧?我和我的孩子们做了一个交易,他们在一周中的某一天和我在一起,他们会得到煎饼。当然,这意味着我也得到了煎饼;)
  • 如果有多个嵌套的捕获组,列表会是什么样子? {(s(t)(ac)k(overf)(low))(.)} 或者是否允许捕获组?
  • 你得到整个匹配的循环结果(stackoverflowa ... stackoverflowe),然后是第一个子匹配(stackoverflow 在每种情况下),然后是四个子匹配(@ 987654338@、acoverflow),最后在每个循环中 (a ... e) 之一(第二个子匹配)。
  • +1 我错误地认为 OP 真的是最后的意思,因为你知道,有时候用文字表达的并不是真正的意思^^;
  • @sln:它返回四个元素:从字符串开头到 ..."flowe" 的大匹配,然后是最后一个子匹配,然后是最后一个子匹配的两个子匹配。但是你知道,我不是 tclsh:你为什么不自己试试呢?
猜你喜欢
  • 2012-09-17
  • 2012-04-06
  • 1970-01-01
  • 1970-01-01
  • 2015-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多