首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Ruby regex多次重复捕获

Ruby regex多次重复捕获
EN

Stack Overflow用户
提问于 2018-03-10 23:38:43
回答 2查看 1.7K关注 0票数 2

为了好玩,我尝试用regex解析网页的一个子集。这很有趣,直到我遇到了下面的问题。我有一个段落如下;

代码语言:javascript
复制
foo: 1, 2, 3, 4 and 5.
bar: 1, 2 and 3.

我要做的是,通过应用以下正则表达式,在该段的第一行中以foo:开头获取数字:

代码语言:javascript
复制
foo:(?:\s(\d)(?:,|\sand|\.))+

这与上面的字符串匹配,但它只捕获捕获组的最后一次出现,即5

如何捕捉以foo:开头的段落中的所有数字,直到使用单个正则表达式首次出现.为止。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-03-11 20:11:16

在大多数编程语言中,重复捕获组的数据不是单独存储的,因此不能单独引用它们。这是使用\G锚点的有效原因。\G使匹配从上一次匹配结束的位置开始,或者它将匹配字符串的开头与\A相同。

因此,我们需要它的第一种能力:

代码语言:javascript
复制
(?:foo:|\G(?!\A))\s*(\d+)\s*(?:,|and)?

细目:

  • (?:启动非捕获组。
    • foo:匹配foo:
    • |
    • \G(?!\A)从上一次比赛结束的位置继续匹配

  • NCG的)末端
  • \s*任意数量的空格字符
  • (\d+)匹配和捕获数字
  • \s*任意数量的白纸字符
  • (?:,|and)?可选,and

此正则表达式将开始匹配在输入字符串中满足foo的情况。然后尝试查找逗号或and前面的以下数字(允许数字周围的空格)。

\K令牌将重置匹配。这意味着它将发送一个信号给引擎,以忘记到目前为止匹配的任何内容(但保留捕获的任何内容),然后将光标留在该位置。

我在Rubular中使用了\K,使结果集没有匹配的字符串,而是捕获到的数字。然而,Rubular的工作方式似乎不同,不需要\K。这根本不是必须的。

票数 4
EN

Stack Overflow用户

发布于 2018-03-11 08:06:28

这个答案只使用一个正则表达式,但无可否认,它做了一些预处理和后置处理。(请给我一点乐趣。我确实认为这里可能有一些教学价值。)

代码语言:javascript
复制
str = "foo: 1, 2, 34, 4 and 5. and 6."

r = /
    \d+             # match one or more digits
    (?=[^.]+:oof\z) # match one or more digits other than a period, followed
                    # by ":oof" at the end of the string, in a positive lookahead
    /x              # free-spacing regex definition mode

str.reverse.scan(r).join(' ').reverse.split
  #=> ["1", "2", "34", "4", "5"]

步骤如下。

代码语言:javascript
复制
s = str.reverse
  #=> ".6 dna .5 dna 4 ,43 ,2 ,1 :oof"
a  = s.scan r
  #=> ["5", "4", "43", "2", "1"]
b  = a.join(' ')
  #=> "5 4 43 2 1"
c  = b.reverse
  #=> "1 2 34 4 5"
c.split
  #=> ["1", "2", "34", "4", "5"]

如果没有匹配,则返回空数组。

为什么要倒车?这是为了允许我使用一个正的前瞻,它不像正向后,允许可变长度的匹配。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49215149

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档