Bug #12862
closedRegular Expression Named Group Matching does not work with #{} (Similar? to issue #2778)
Description
Loading development environment (Rails 4.2.5)
irb(main):001:0> /\$(?<dollars>\d+)\.(?<cents>\d+)/ =~ "$3.67"
=> 0
irb(main):002:0> dollars
=> "3"
BUT:
irb(main):001:0> numbers = '\d+'
=> "\\d+"
irb(main):002:0> /\$(?<dollars>#{numbers})\.(?<cents>\d+)/ =~ "$3.67"
=> 0
irb(main):003:0> dollars
NameError: undefined local variable or method `dollars' for main:Object
Updated by Hanmac (Hans Mackowiak) over 7 years ago
it did took me a while to understand what you mean, because the regexp are displayed wrong.
"When named capture groups are used with a literal regexp on the left-hand side of an expression and the =~ operator, the captured text is also assigned to local variables with corresponding names."
it might not be good explained, but that literal regexp can not have interpolation for that to work.
Updated by Amig0 (Leo Amigud) over 7 years ago
Hans Mackowiak wrote:
it did took me a while to understand what you mean, because the regexp are displayed wrong.
"When named capture groups are used with a literal regexp on the left-hand side of an expression and the =~ operator, the captured text is also assigned to local variables with corresponding names."
it might not be good explained, but that literal regexp can not have interpolation for that to work.
Sorry, not sure what you mean.
As a matter of fact i can use regexp like:
irb(main):013:0> numbers = '\d+'
=> "\d+"
irb(main):014:0> /$#{numbers}.\d+/ =~ "$3.67"
=> 0
irb(main):015:0>
to match the string, but using #{numbers} inside the named group somehow does not work.
Is that the expected behaviour?
Leo
Updated by phluid61 (Matthew Kerwin) over 7 years ago
Leo Amigud wrote:
Sorry, not sure what you mean.
As a matter of fact i can use regexp like:
irb(main):013:0> numbers = '\d+'
=> "\d+"
irb(main):014:0> /$#{numbers}.\d+/ =~ "$3.67"
=> 0
irb(main):015:0>to match the string, but using #{numbers} inside the named group somehow does not work.
Is that the expected behaviour?
Leo
It's what Hans quoted and said:
"When named capture groups are used with a literal regexp [i.e. not an interpolated regexp] ... the captured text is also assigned to local variables ..."
/(?<dollars>#{numbers})/
is interpolated, not literal.
If you want to use interpolation and named captures, you can still get there using #match:
irb(main):001:0> numbers = '\d+'
=> "\\d+"
irb(main):002:0> md = /\$(?<dollars>(#{numbers})).(?<cents>\d+)/.match "$4.67"
=> #<MatchData "$4.67" dollars:"4" cents:"67">
irb(main):003:0> md['dollars']
=> "4"
irb(main):004:0> md['cents']
=> "67"
or:
irb(main):001:0> numbers = '\d+'
=> "\\d+"
irb(main):002:0> /\$(?<dollars>(#{numbers})).(?<cents>\d+)/ =~ "$4.67"
=> 0
irb(main):003:0> $~['dollars']
=> "4"
irb(main):004:0> $~['cents']
=> "67"
Updated by Amig0 (Leo Amigud) over 7 years ago
Matthew Kerwin wrote:
Leo Amigud wrote:
Sorry, not sure what you mean.
As a matter of fact i can use regexp like:
irb(main):013:0> numbers = '\d+'
=> "\d+"
irb(main):014:0> /$#{numbers}.\d+/ =~ "$3.67"
=> 0
irb(main):015:0>to match the string, but using #{numbers} inside the named group somehow does not work.
Is that the expected behaviour?
Leo
It's what Hans quoted and said:
"When named capture groups are used with a literal regexp [i.e. not an interpolated regexp] ... the captured text is also assigned to local variables ..."
/(?<dollars>#{numbers})/
is interpolated, not literal.If you want to use interpolation and named captures, you can still get there using #match:
irb(main):001:0> numbers = '\d+' => "\\d+" irb(main):002:0> md = /\$(?<dollars>(#{numbers})).(?<cents>\d+)/.match "$4.67" => #<MatchData "$4.67" dollars:"4" cents:"67"> irb(main):003:0> md['dollars'] => "4" irb(main):004:0> md['cents'] => "67"
or:
irb(main):001:0> numbers = '\d+' => "\\d+" irb(main):002:0> /\$(?<dollars>(#{numbers})).(?<cents>\d+)/ =~ "$4.67" => 0 irb(main):003:0> $~['dollars'] => "4" irb(main):004:0> $~['cents'] => "67"
Thank you for the explanation!
Leo
Updated by shyouhei (Shyouhei Urabe) over 7 years ago
- Description updated (diff)
Updated by jeremyevans0 (Jeremy Evans) over 4 years ago
- Status changed from Open to Closed