From: Ross Bamford Date: 2005-12-22T22:42:49+09:00 Subject: Re: Regular expression question On Thu, 22 Dec 2005 09:42:00 -0000, Robert Klemme wrote: > Ross Bamford wrote: >> On Wed, 21 Dec 2005 18:03:13 -0000, DeZo wrote: >> >>> Why does the following code: >>> >>> line = " rows = 10 cols = 1 occupied cells = 0" >>> line =~ /.*(\d+).*(\d+).*(\d+)/ >>> print(" scanned rows = ",$1," cols = ",$2," occ = ",$3,"\n") >>> >>> print this when it runs: >>> >>> scanned rows = 0 cols = 1 occ = 0 >>> >>> (notice rows is zero!) >>> >>> What have I done wrong? >> >> Your problem is that '*' is greedy so it'll match as many 'any >> characters' as it can. Try >> >> /.*?(\d+).*?(\d+).*?(\d+)/ >> >> Usually I'd tend to use something like: >> >> /[^\d]*(\d+)[^\d]*(\d+)[^\d]*(\d+)/ >> >> instead, to make it explicit I want not digits, followed by digits, >> etc... > > Some other solutions with individual pros and cons: > >>> line = " rows = 10 cols = 1 occupied cells = 0" > => " rows = 10 cols = 1 occupied cells = 0" >>> line.scan(/\d+/) > => ["10", "1", "0"] >>> line.scan(/\d+/).map {|s| s.to_i} > => [10, 1, 0] >>> line.scan(/\w+\s*=\s*(\d+)/) > => [["10"], ["1"], ["0"]] >>> line.scan(/\w+\s*=\s*(\d+)/).map {|m| m[0].to_i} > => [10, 1, 0] > Ahh, much better. Another KISS reminder gets it's own page (again) in my notebook.. Thanks :) -- Ross Bamford - rosco@roscopeco.remove.co.uk