Ruby Regexp组匹配,在1行上分配variables

我目前正试图将一个string重新映射到多个variables。 示例string:

ryan_string = "RyanOnRails: This is a test" 

我用这个正则expression式匹配它,有3个组:

 ryan_group = ryan_string.scan(/(^.*)(:)(.*)/i) 

现在要访问每个组,我必须做这样的事情:

 ryan_group[0][0] (first group) RyanOnRails ryan_group[0][1] (second group) : ryan_group[0][2] (third group) This is a test 

这看起来很荒谬,感觉就像我做错了什么。 我希望能够做到这样的事情:

 g1, g2, g3 = ryan_string.scan(/(^.*)(:)(.*)/i) 

这可能吗? 还是有比我更好的方法吗?

你不想scan这个,因为它没有什么意义。 您可以使用String#match返回一个MatchData对象,然后调用#captures返回一个捕获数组。 像这样的东西:

 #!/usr/bin/env ruby string = "RyanOnRails: This is a test" one, two, three = string.match(/(^.*)(:)(.*)/i).captures p one #=> "RyanOnRails" p two #=> ":" p three #=> " This is a test" 

请注意,如果找不到匹配项, String#match将返回零,所以类似这样的工作可能会更好:

 if match = string.match(/(^.*)(:)(.*)/i) one, two, three = match.captures end 

虽然scan确实没有什么意义。 它仍然可以完成这个工作,你只需要先将返回的数组展平。 one, two, three = string.scan(/(^.*)(:)(.*)/i).flatten

你可以使用Match或者=〜来代替,这样可以给你一个单独的匹配,你可以以相同的方式访问匹配数据,也可以使用特殊的匹配variables$ 1,$ 2,$ 3

就像是:

 if ryan_string =~ /(^.*)(:)(.*)/i first = $1 third = $3 end 

您可以命名您捕获的匹配

 string = "RyanOnRails: This is a test" /(?<one>^.*)(?<two>:)(?<three>.*)/i =~ string puts one, two, three 

如果你颠倒了string和正则expression式的顺序,它是行不通的。

scan()会在你的string中find正则expression式的所有非重叠匹配,所以不是像你期待的那样返回一个你的组的数组,而是返回一个数组数组。

你可能最好使用match() ,然后使用MatchData#captures数组:

 g1, g2, g3 = ryan_string.match(/(^.*)(:)(.*)/i).captures 

但是,如果您想要使用scan()也可以这样做:

 g1, g2, g3 = ryan_string.scan(/(^.*)(:)(.*)/i)[0] 

你必须决定是否是一个好主意,但ruby正则expression式可以为你定义局部variables!

我还不确定这个function是真棒还是完全疯狂,但你的正则expression式可以定义局部variables。

 ryan_string = "RyanOnRails: This is a test" /^(?<webframework>.*)(?<colon>:)(?<rest>)/ =~ ryan_string^ # This defined three variables for you. Crazy, but true. webframework # => "RyanOnRails" puts "W: #{webframework} , C: #{colon}, R: #{rest}" 

(看看http://ruby-doc.org/core-2.1.1/Regexp.html ,search“本地variables”)。

注意:正如在评论中指出的那样,我发现@toonsend( https://stackoverflow.com/a/21412455 )对这个问题有一个相似和较早的答案。 我不认为我是“偷”,但如果你想公平地赞美和荣誉的第一个答案,请随时:)我希望没有动物受到伤害。