在Ruby的正则表达式中命名捕获

时间:2014-09-10 09:08:31

标签: ruby regex

我正在尝试从具有相对较长的正则表达式的文本行中提取信息。下面是一个描述问题的简化正则表达式。

line = "Internet  10.9.68.178           127   c07b.bce9.7d41  ARPA   Vlan2"

如果我尝试直接匹配此行而不尝试“保存”#39;正则表达式变量,它运行良好:

[223] pry(main)> /Internet\s+(?<ipaddr>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/  =~ line
=> 0
[224] pry(main)> ipaddr
=> "10.9.68.178"
[225] pry(main)> $1
=> "10.9.68.178"

现在,当我尝试使用&#39;存储&#39;做同样的事情时版本的正则表达式,它失败了:

  [226] pry(main)> ipaddr = nil   # ensure that it's cleared before match

  [227] pry(main)> myreg = /Internet\s+(?<ipaddr>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/
  => /Internet\s+(?<ipaddr>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/
  [228] pry(main)> myreg =~ line
  => 0
  [229] pry(main)> ipaddr
  => nil
  [230] pry(main)> $1
  => "10.9.68.178"

我还试图直接调用match方法,它似乎有效:

[231] pry(main)> myreg.match(line)
=> #<MatchData "Internet  10.9.68.178" ipaddr:"10.9.68.178">

但这意味着我需要做一个简单的if语句:

if m = myreg.match(line)
   do_stuff m[:ipaddr]
end

而不是简单

if myreg =~ line
   do_stuff ipaddr
end

关于为什么在这种情况下没有正确捕获名称的任何想法?

1 个答案:

答案 0 :(得分:1)

有趣。我在Ruby Documentation中查看了这个内容。

它说:

  

如果正则表达式不是文字,则不会发生分配。

这就是/Internet\s+(?<ipaddr>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/ =~ line有效的原因,但myreg =~ line没有。

感谢您让我学到新东西。 :)