正则表达式 - 在每个组中获得多个匹配

时间:2015-12-07 19:10:04

标签: ruby regex pattern-matching regex-greedy

我有一个这样的字符串: raw_string = "(a=1)(b=2)(c=3)"

我想匹配它并在每组括号中获取值,并将每个结果都放在一个组中。 例如:

组0 = "a=1"

第1组= "b=2"等等......

我已经尝试了/(\(.*\))/g,但它似乎无效。有人可以帮我这个吗?

谢谢!

3 个答案:

答案 0 :(得分:3)

str = "(a=1)(b=2)  (c=3)"

正如@stribizhev的评论所示:

r = /
    \(       # Match a left paren
    ([^\)]+) # Match >= 1 characters other than a right paren in capture group 1
    \)       # Match a right paren
    /x       # extended/free-spacing regex definition mode

str.scan(r).flatten
  #=> ["a=1", "b=2", "c=3"] 

注意([^\)]+)可以替换为(.+?),使其成为任何角色的懒惰匹配,就像我在使用外观而非捕获组的替代正则表达式中所做的那样:

r = /
    (?<=\()  # Match a left paren in a positive lookbehind
    .+?      # Match >= 1 characters lazily
    (?=\))   # Match a right paren in a positive lookahead
    /x

在这里,lookbehind可以被\(\K取代,其中写着“匹配一个左手,然后忘记到目前为止匹配的所有东西”。

最后,你可以在右边然后左边的paren上使用String#split,可能用空格分隔,然后删除第一个左边和右边的parens:

str.split(/\)\s*\(/).map { |s| s.delete '()' }
  #=> ["a=1", "b=2", "c=3"] 

如果我们可以写s.strip(/[()]/),那会不会很好?

答案 1 :(得分:2)

如果你的意思是带括号的模式恰好出现三次(或不同的固定次数),那么就有可能,但是如果你想让模式出现任意次数,那么你可以'吨即可。 正则表达式只能有固定数量的捕获或命名捕获。

答案 2 :(得分:-2)

只是为了表明你可以让他们进入任意数量的捕获组:

"(a=1)(b=2)(c=3)"[/#{'(?:\((.*?)\))?' * 99}/]
[$1, $2, $3]
#=> ["a=1", "b=2", "c=3"]