如何在ruby中进行命名捕获

如何在ruby中进行命名捕获,ruby,regex,Ruby,Regex,我想命名从扫描中获取的字符串捕获。怎么做 "555-333-7777".scan(/(\d{3})-(\d{3})-(\d{4})/).flatten #=> ["555", "333", "7777"] 有可能把它变成这样吗 {:area => "555", :city => "333", :local => "7777" } 或 我试过了 "555-333-7777".scan(/((?<area>)\d{3})-(\d{3})-(\d{4})/).f

我想命名从扫描中获取的字符串捕获。怎么做

"555-333-7777".scan(/(\d{3})-(\d{3})-(\d{4})/).flatten #=> ["555", "333", "7777"]
有可能把它变成这样吗

{:area => "555", :city => "333", :local => "7777" }

我试过了

"555-333-7777".scan(/((?<area>)\d{3})-(\d{3})-(\d{4})/).flatten

您应该对命名捕获使用
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"
或者这个(ruby 2.4或更高版本)

像这样的

"555-333-7777" =~ /^(?<area>\d+)\-(?<city>\d+)\-(?<local>\d+)$/
Hash[$~.names.collect{|x| [x.to_sym, $~[x]]}]
 => {:area=>"555", :city=>"333", :local=>"7777"}

将捕获组名称及其值转换为散列的一种方法是使用带有命名捕获的正则表达式,使用
(?
),然后访问
%~
全局“last match”变量

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"}
regex_与_命名的_捕获_组=%r'(?\d{3})-(?\d{3})-(?\d{4})'
“555-333-7777”[带有命名组的正则表达式]
match|hash=$~.names.injection({}){mem,capture{mem[capture]=$~[capture];mem}
#=>{“区域”=>“555”、“城市”=>“333”、“本地”=>“7777”}
#如果ActiveSupport可用
匹配\u散列。符号化\u键!
#=>{地区:“555”,城市:“333”,地方:“7777”}

如果您真的不需要哈希,只需要局部变量:

if /(?<area>\d{3})-(?<city>\d{3})-(?<number>\d{4})/ =~ "555-333-7777"
  puts area
  puts city
  puts number
end
if/(?)

将命名捕获组与 表达式的左侧和=~运算符,即捕获的文本 也被分配给具有相应名称的局部变量


我尝试了“555-333-7777”。扫描(/(?)\d{3})-(\d{3})-(\d{4})/).flatte`但它返回
[]
始终在你的问题中显示你试图表明你已经做出了努力并避免否决投票的任何方法。在Ruby 2.4.0中,我们得到:
m.named_捕获了{“area”=>“555”、“city”=>“333”、“number”=>“7777”
m.named_captures # => {"area"=>"555", "city"=>"333", "number"=>"7777"}
"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"}
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"}
if /(?<area>\d{3})-(?<city>\d{3})-(?<number>\d{4})/ =~ "555-333-7777"
  puts area
  puts city
  puts number
end