From: William James Date: 2005-12-16T15:52:45+09:00 Subject: Re: repeated regular expressions -- Need addition to Matchdata Garance A Drosehn wrote: > Right now what ruby does is it only saves the *last* copy of > however many things it matched. It does seem to me that it > should save *all* copies of what it matched -- somewhere. > > For instance, let's say that Matchdata included another > method called "repeated", and that method returns an array. > This array has the same number of elements as captures > does. If the pattern-segment for captures[0] is NOT a repeating > pattern, then repeated[0] returns nil. If captures[1] is tied to a > pattern-segment that does (possibly) repeat, then repeated[1] > returns an array of strings, one element for each time that > pattern-segment was found. > > Eg: > > /^(copy|duplicate) \s+ (\w+\s+)+ (before|after) \s+ (\w+\s*)+ $/x > > used to match against the string: > "copy apple pear plum peach after bill bob' > > $~.captures[0] == "copy" > $~.repeated[0] == nil > $~.captures[1] == "peach " > $~.repeated[1] == {"apple ", "pear ", "plum ", "peach "} > $~.captures[2] == "after" > $~.repeated[2] == nil > $~.captures[3] == "bob" > $~.repeated[3] == {"bill ", "bob"} > > Note that I wouldn't even need to add the extra '()' around > '(\w+\s+)+' if ruby provided something like this. > > Of course, the next question is why not just make captures[1] > be the array of "things" which were repeatedly matched, instead > of only holding the last-instance of that repeated pattern. That > would work fine, IMO, although I guess it might break the scripts > of some people. Looks like a logical and natural extension. Until it's added, perhaps something like this would suffice: pat1 = /\w+\s+/ pat2 = /\w+\s*/ DATA.each {|line| line.chomp! md = /^(?:copy|duplicate) \s+ ((?: #{ pat1 } )+) (?:after|before) \s+ ((?: #{ pat2 } )+) $ /x.match( line ) p md.captures src_food = md.captures.first.scan( pat1 ) dest_word = md.captures.last.scan( pat2 ) p src_food, dest_word } __END__ copy apple pear plum peach after bill bob duplicate tomato before joe alice alfred tommy jane