# Re: repeated regular expressions -- Need addition to Matchda

**URL:** <https://www.ruby-forum.com/t/re-repeated-regular-expressions-need-addition-to-matchda/50422>\
**Category:** Ruby\
**Created:** [December 16, 2005, 3:20am UTC](https://www.ruby-forum.com/t/re-repeated-regular-expressions-need-addition-to-matchda/50422 "2005-12-16T03:20:55Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Garance\_A\_Drosehn](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/ccd318/32.png) [@Garance\_A\_Drosehn](https://www.ruby-forum.com/u/Garance_A_Drosehn)\
**Post date:** [December 16, 2005, 3:20am UTC](https://www.ruby-forum.com/t/re-repeated-regular-expressions-need-addition-to-matchda/50422/1 "2005-12-16T03:20:55Z")

</div>

On 12/15/05, William J. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > ```
> > destword = ["bill ", "bob"]
> > 
> > ```
> > 
> > [“copy”, "apple pear plum peach ", "peach ", “after”, “bill bob”, “bob”]  
> > dest\_word = md.captures.last.split  
> > p src\_food, dest\_word  
> > }

This does happen to solve my specific example, but…

…that split only works because “you know” what the repeating  
pattern is. While it does not explicitly repeat the original regex,  
that split does the job only because the repeating pattern does  
not include blanks. Don’t look at the _specific_ pattern that I  
am repeating, but try to imagine _any_ repeating pattern at  
that point in the example. Right now, can we come up with a  
solution where I can replace that pattern with _anything_ I want  
to repeat, and the solution still works?

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.

---

<div class="post-metadata">

**Author:** ![Garance\_A\_Drosehn](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/ccd318/32.png) [@Garance\_A\_Drosehn](https://www.ruby-forum.com/u/Garance_A_Drosehn)\
**Post date:** [December 16, 2005, 7:54am UTC](https://www.ruby-forum.com/t/re-repeated-regular-expressions-need-addition-to-matchda/50422/2 "2005-12-16T07:54:34Z")

</div>

Garance A Drosehn wrote:

> returns an array of strings, one element for each time that  
> $~.repeated[0] == nil  
> 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
