Reputation: 182
I am trying to extract information from a line of text with relatively long regular expression. Below is a simplified regexp that describes the problem.
line = "Internet 10.9.68.178 127 c07b.bce9.7d41 ARPA Vlan2"
If I try to match this line directly without trying to 'save' regexp into a variable, it works very well:
[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"
Now, when I try to do exact same thing with 'stored' version of the regexp, it fails miserably:
[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"
I have also tried to call match
method directly and it seems to work:
[231] pry(main)> myreg.match(line)
=> #<MatchData "Internet 10.9.68.178" ipaddr:"10.9.68.178">
but this means for a simple if
statement I need to do something like this:
if m = myreg.match(line)
do_stuff m[:ipaddr]
end
instead of simply
if myreg =~ line
do_stuff ipaddr
end
Any ideas as to why the names are not captured correctly in this instance?
Upvotes: 1
Views: 92
Reputation: 40526
Interesting. I've looked this up in the Ruby Documentation.
It says there:
The assignment does not occur if the regexp is not a literal.
That's why /Internet\s+(?<ipaddr>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/ =~ line
works, but myreg =~ line
does not.
Thanks for making me learn something new. :)
Upvotes: 1