我正在尝试使用正则表达式解析网页的子集,只是为了好玩。本来很有趣,直到我遇到了以下问题。我有一个像下面这样的段落;
foo: 1, 2, 3, 4 and 5.
bar: 1, 2 and 3.
我想做的是,通过应用以下正则表达式获取以 foo:
开头的段落第一行中的数字:
foo:(?:\s(\d)(?:,|\sand|\.))+
这与上面的字符串匹配,但它仅捕获捕获组的最后一个匹配项,即 5
。
如何使用单个正则表达式模式捕获以 foo:
开头的段落中的所有数字,直到第一次出现 .
。
最佳答案
在大多数编程语言中,重复捕获组的数据不会单独存储,因此您无法单独引用它们。这是使用 \G
anchor 的充分理由。 \G
导致匹配从上一个匹配结束的位置开始,或者它将匹配字符串的开头,与 \A
相同。
所以我们需要它的第一个功能:
(?:foo:|\G(?!\A))\s*(\d+)\s*(?:,|and)?
分割:
(?:
启动非捕获组foo:
匹配foo:
|
或者\G(?!\A)
从上一场比赛结束的地方继续比赛
)
NCG 结束\s*
任意数量的空白字符(\d+)
匹配并捕获数字\s*
任意数量的空格字符(?:,|and)?
可选、
或and
此正则表达式将在输入字符串中遇到 foo
时开始匹配。然后尝试查找逗号或 and
之前的后续数字(数字周围允许有空格)。
\K
token 将重置匹配。这意味着它将向引擎发送一个信号,以忘记到目前为止匹配的任何内容(但保留捕获的任何内容),然后将光标留在该位置。
我在 Rubular 正则表达式中使用 \K
来使结果集不包含匹配的字符串,但捕获数字。然而,Rubular 的工作方式似乎有所不同,并且不需要 \K
。这根本不是必须的。
关于Ruby 正则表达式多次重复捕获,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49215149/