From: Robert Klemme Date: 2010-07-27T05:40:15+09:00 Subject: Re: Regex ^ beginning not strong? On 07/26/2010 06:01 PM, Iain Barnett wrote: > Hi, > > I've some more regex questions. I wrote a pattern to check for valid > regexes and inspect the parts (we all have our reasons for the things > we do:) It wasn't working so I went down to simpler and simpler > patterns, but I'm a bit surprised at the way Ruby 1.9 is handling the > regexes. I tested the same pattern in Perl and it came out with the > answers I'd expect. > > Is this down to me using perl regexes for so long, or is there > something I'm missing about Ruby's implementation? It appears ^ at > the beginning of a string doesn't bind as strongly as I'd expect. > > > I believe this test should fail as should be bound to the > beginning of the string by the ^ , and the match result is a little > bit crazy - shouldn't the main capture be "d\\d" if it's following > the logical route it's chosen? $ ruby -e ' md = > /^(?m)?(?.)(?.+?)\g/.match( %q!/\d\d\\d! ) > puts md.inspect ' # > I think you found a bug - probably related to referring to back references to named capturing groups: irb(main):013:0> s = %q!/\d\d\\d! => "/\\d\\d\\d" irb(main):027:0> r = /^(?m)?(?.)(?.+?)/ => /^(?m)?(?.)(?.+?)/ irb(main):028:0> md = r.match s => # This must not match at all: irb(main):029:0> r = /^(?m)?(?.)(?.+?)\g/ => /^(?m)?(?.)(?.+?)\g/ irb(main):030:0> md = r.match s => # It seems to work better with numbered capturing groups irb(main):027:0> r = /^(?m)?(?.)(?.+?)/ => /^(?m)?(?.)(?.+?)/ irb(main):028:0> md = r.match s => # irb(main):029:0> r = /^(?m)?(?.)(?.+?)\g/ => /^(?m)?(?.)(?.+?)\g/ irb(main):030:0> md = r.match s => # Normal greediness: irb(main):035:0> r = /^(m)?(.)(.+)\2/ => /^(m)?(.)(.+)\2/ irb(main):036:0> md = r.match s => nil This works: irb(main):038:0> /^(m)?(.)(.+)\2/.match 'abbba' => # Maybe the numbering gets out of order if we try to mix: irb(main):039:0> /^(?m)?(.)(.+)\2/.match 'abbba' SyntaxError: (irb):39: numbered backref/call is not allowed. (use name): /^(?m)?(.)(.+)\2/ from /usr/local/bin/irb19:12:in `
' irb(main):040:0> /^(?m)?(.)(.+)\k<2>/.match 'abbba' SyntaxError: (irb):40: numbered backref/call is not allowed. (use name): /^(?m)?(.)(.+)\k<2>/ from /usr/local/bin/irb19:12:in `
' irb(main):041:0> irb(main):047:0> RUBY_VERSION => "1.9.1" irb(main):048:0> RUBY_PATCHLEVEL => 376 Frankly, I never used named capturing groups yet (simply for habit and compatibility). It was probably a good choice so far. Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/