Ruby 正则表达式多次重复捕获

标签 ruby regex

我正在尝试使用正则表达式解析网页的子集,只是为了好玩。本来很有趣,直到我遇到了以下问题。我有一个像下面这样的段落;

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/

相关文章:

regex - 正则表达式在数字和字符之间添加空格

regex - 正则表达式追踪器

c# - C# 中的正则表达式,这可能吗?

ruby-on-rails - 避免对 rails 中的表进行多次查询

ruby - 不转换成字符串,一个Fixnum有多少位数?

php - 正则表达式,截断以缩短文章并用省略号代替标点符号?

python - 如何在 Python 中使用列表/数组进行字符串替换?

ruby-on-rails - 权限被拒绝回形针和 s3 错误

ruby - HashMap 方法

ruby - 传递给 `instance_exec` 时如何执行 proc