【问题标题】:Simple regex match works on rubular but not in IRB简单的正则表达式匹配适用于 rubular 但不适用于 IRB
【发布时间】:2013-10-19 06:46:29
【问题描述】:

给定字符串:

"hello %{one} there %{two} world"

此代码不起作用:

s = "hello %{one} there %{two} world"
r = Regexp.new(/(%{.*?})+/)
m = r.match(s)
m[0] # => "%{one}"
m[1] # => "%{one}" 
m[2] # => nil  # I expected "%{two}"

但在Rubular 上,相同的正则表达式(%{.*?}) 可以工作并返回%{one}%{two}

我做错了什么?

【问题讨论】:

    标签: ruby regex


    【解决方案1】:

    使用String#scan方法:

    'hello %{one} there %{two} world'.scan(/(%{.*?})/)
    # => [["%{one}"], ["%{two}"]]
    

    使用非捕获组:

    'hello %{one} there %{two} world'.scan(/(?:%{.*?})/)
    # => ["%{one}", "%{two}"]
    

    UPDATE实际上,不需要分组。

    'hello %{one} there %{two} world'.scan(/%{.*?}/)
    # => ["%{one}", "%{two}"]
    

    【讨论】:

    • 谢谢,这行得通。但是为什么 Regexp 不返回匹配项,你知道吗?
    • @Zabba, String#match 使用 Regexp#match 返回 MatchObject;表示单个匹配项。我不知道方法设计决策历史。
    • 啊,我明白了。因此,使 Regex /(%{.*}).*(%{.*})/ 返回匹配项。谢谢!
    • 另外,虽然 {} 在指定要捕获的项目数量时具有特殊含义,但它们不必被转义,除非它们应该匹配的模式看起来像它'适合{[\d,]+}。正则表达式引擎非常聪明,可以区分。请注意,我之前评论中的示例无需转义即可工作。
    • 我同意铁皮人的观点。另外,去掉+,因为它几乎肯定不属于它。还有分组,这是不必要的。剩下的就是:/%{.*?}/,但更有效的是/%{[^}]*}/。哎呀,我想我会发布一个新答案。
    【解决方案2】:
    'hello %{one} there %{two} world'.scan /%{[^}]*}/
    #=> ["%{one}", "%{two}"]
    

    【讨论】:

      【解决方案3】:

      这是供将来参考的,因为这是在 Google 上弹出的第一个问题。

      我刚刚遇到了这个问题,我的测试在 Rubular 上工作,但是当我运行我的代码时,它们没有工作。

      我正在测试类似/^<regex-goes-here>$/

      结果我测试的正则表达式以回车符结尾 \n\r 但我没有将它们复制到 Rubular,所以它们当然不匹配。

      希望这会有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-10-10
        • 2018-11-13
        • 1970-01-01
        • 1970-01-01
        • 2016-06-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多