我想命名从扫描中获取的字符串的捕获。怎么做?
"555-333-7777".scan(/(\d{3})-(\d{3})-(\d{4})/).flatten #=> ["555", "333", "7777"]
是否可以将其变成这样的
{:area => "555", :city => "333", :local => "7777" }
或
[["555","area"], [...]]
我试过
"555-333-7777".scan(/((?<area>)\d{3})-(\d{3})-(\d{4})/).flatten
但它返回
[]
答案 0 :(得分:80)
您应该match
使用已命名的捕获,而不是scan
m = "555-333-7777".match(/(?<area>\d{3})-(?<city>\d{3})-(?<number>\d{4})/)
m # => #<MatchData "555-333-7777" area:"555" city:"333" number:"7777">
m[:area] # => "555"
m[:city] # => "333"
如果你想要一个实际的哈希,你可以使用这样的东西:
m.names.zip(m.captures).to_h # => {"area"=>"555", "city"=>"333", "number"=>"7777"}
或者这个(红宝石2.4或更高版本)
m.named_captures # => {"area"=>"555", "city"=>"333", "number"=>"7777"}
答案 1 :(得分:6)
这样的东西?
"555-333-7777" =~ /^(?<area>\d+)\-(?<city>\d+)\-(?<local>\d+)$/
Hash[$~.names.collect{|x| [x.to_sym, $~[x]]}]
=> {:area=>"555", :city=>"333", :local=>"7777"}
奖金版本:
Hash[[:area, :city, :local].zip("555-333-7777".split("-"))]
=> {:area=>"555", :city=>"333", :local=>"7777"}
答案 2 :(得分:0)
将捕获组名称及其值转换为哈希的方法是使用带有(?<capture_name>
命名捕获的正则表达式,然后访问%~
全局&#34;最后一个匹配&#34;变量
regex_with_named_capture_groups = %r'(?<area>\d{3})-(?<city>\d{3})-(?<local>\d{4})'
"555-333-7777"[regex_with_named_capture_groups]
match_hash = $~.names.inject({}){|mem, capture| mem[capture] = $~[capture]; mem}
# => {"area"=>"555", "city"=>"333", "local"=>"7777"}
# If ActiveSupport is available
match_hash.symbolize_keys!
# => {area: "555", city: "333", local: "7777"}
答案 3 :(得分:0)
如果你真的不需要散列,而只需要局部变量:
if /(?<area>\d{3})-(?<city>\d{3})-(?<number>\d{4})/ =~ "555-333-7777"
puts area
puts city
puts number
end
它是如何工作的?
=~
正则表达式运算符。string =~ regex
,它不起作用。?<var>
与 named_captures
相同。当命名捕获组与文字正则表达式一起使用时 表达式的左侧和 =~ 运算符,捕获的文本 也分配给具有相应名称的局部变量。