正则表达式扫描结果不会记录进一步的正则表达式命中?

时间:2013-11-25 23:56:06

标签: ruby regex

我正在使用Ruby中的递归正则表达式解析伪S表达式。

在做了一些搜索后,我开始使用“Matching balanced parenthesis in Ruby using recursive regular expressions like perl”答案中使用的正则表达式。正则表达式匹配正确,但结果表现出奇怪的行为。如果我尝试在任何结果上使用match,则无论使用何种正则表达式,这些进一步的结果都将匹配整个测试的字符串。如果我使用字符串文字显式覆盖其中一个初始结果,那么match将按预期为该结果工作。但是,结果条目的类无疑声称它是一个简单的普通字符串。到底是怎么回事?

src = "(def foo 10) (+ foo 4 12)"

def parse(exp)

     expression =%r{
      (?<re>
        \(
          (?:
        (?> [^()]+ )
        |
        \g<re>
          )*
        \)
      )
    }x
     trans = ""
     exp.scan(expression) {|m|
      m[0].match(/\d/) {|m|
          trans += m.string
     }
     } 
     return trans
end

当然,这甚至不完全解析代码。我也知道尝试使用正则表达式来强大地解析代码并不是一个好主意,但我并不是想要一个强大的解决方案,只是一个POC。

有谁知道是什么导致这些正则表达式行为异常?

1 个答案:

答案 0 :(得分:0)

来自string的方法MatchData返回“中传递的字符串的冻结副本以匹配”,而不是匹配的内容。每http://www.ruby-doc.org/core-2.0.0/MatchData.html#method-i-string

这就是为什么你要返回整个字符串的原因,因为你要将每个初始匹配添加到trans

您可以通过在最里面的块中放入m值的打印语句来确认这一点。 match正确匹配1,然后是4