From: "Ara.T.Howard" Date: 2004-05-14T22:13:54+09:00 Subject: Re: Regexp Error? On Fri, 14 May 2004, Robert Klemme wrote: > > "ts" schrieb im Newsbeitrag > news:200405141118.i4EBIo422693@moulon.inra.fr... > > >>>>> "R" == Robert Klemme writes: > > > > R> irb(main):023:0> "123-456".gsub(/.*/, 'X') > > R> => "XX" > > > > * first match : "123-456" > > * now it's at end > > * second match with the empty string > > > > R> irb(main):024:0> "123-456".gsub(/^.*/, 'X') > > R> => "X" > > > > * first match : "123-456" > > * now it's at end > > * it can't match the empty string because there is ^ in the regexp > > That explains it. I still have to say that I find this a bit surprising. > Moreover, case strikes me as error: > > irb(main):025:0> "123-456".gsub(/.*$/, 'X') > => "XX" > > Applying your explanation, one would have to say that "$" is matched > twice. IMHO this is not correct. Or is there another explanation why > this gsub happens to return "XX"? > > Regards > > robert ^ and $ are special and they consume no chars and so are not really 'matched' in the same way... your regex says 'zero or more chars before the end of a string' so you get ^ 1 2 3 - 4 5 6 $ --------------- ^ the first go then then scanning starts again - the problem is that it's then looking for something potentially zero widthed followed by something zero widthed - which is always going to match (again). i guess the difference for the second match is that it does not advance the scanner ptr and can therefore know it's done... it does seem odd, but without that behaviour it would be hard to match empty strings, line boundries, and other zero widthed things... for instance if you did this "123-456".gsub(/.*|$/, 'X') you would expect 'XX', where the second 'X' is inserted into a zero width position and '.*' does not include '$' and yet this is realy the same exact behaviour - scanning is done again from the non-space before the end of line, allowing you to finally match '$' which '.*' did not consume. regexs can be so tricky, i _try_ to use these rules with them * always use both ^ and $ (this makes it a lot harder to write the expression too!) * never use .* (or * at all really) the last is actually pretty important - we use a product here, ldm (local data manager), that scans a huge memeory mapped queue full of data products matched a list of actions against the product tags. the list of actions use regexps and all of ours had '.*' in them. top showed the ldm process at around 30% cpu - reworking the patterns to not include '.*' dropped it off the rader. -a -- =============================================================================== | EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov | PHONE :: 303.497.6469 | ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328 | URL :: http://www.ngdc.noaa.gov/stp/ | TRY :: for l in ruby perl;do $l -e "print \"\x3a\x2d\x29\x0a\"";done ===============================================================================