From: Gennady Date: 2004-06-11T08:22:48+09:00 Subject: Re: String#scan strangeness David A. Black wrote: > Hi -- > > On Fri, 11 Jun 2004, Gennady wrote: > > >>Simon Strandgaard wrote: >> >> >>>On Thursday 10 June 2004 18:49, Gennady wrote: >>> >>> >>>>I am just wondering why String#scan "looses" a group in every match. I >>>>would expect the following result: >>> >>> >>>when using sub-captures, then #scan returns an array of sub-captures. >>>This does not include capture[0].. which is the full-match. >>> >>>"abcd".scan(/(.)(.)/) >>>#=> [["a", "b"], ["c", "d"]] >>> >>>when not using sub-captures at all, then #scan returns only full-matches. >>> >>>"abcd".scan(/../) >>>#=> ["ab", "cd"] >>> >>>-- >>>Simon Strandgaard >>> >> >>In my original irb session capture I have sub-captures, moreover they >>are nested: >> >>[linux.gfbs:281]gfb> ruby -v >>ruby 1.6.8 (2003-10-15) [i686-linux] >>[linux.gfbs:282]gfb> irb >>irb(main):001:0> a = "a b c d " >>=> "a b c d " >>irb(main):002:0> a.scan %r{((\S+\s+){2,2})} >>ACTUAL => [["a b ", "b "], ["c d ", "d "]] >>I EXPECT => [["a b ", "a ", "b "], ["c d ", "c ", "d "]] > > > My understanding is: you've only got two sets of parentheses, so you > can have at most two captures; in other words, (){2} != ()() :-) It's > purely positional: whatever is in the nth set of parentheses from the > left when the matching stops is the nth capture. > > It's as if each () is a window which can move through the string but > can only hold one substring. So the second set of () sort of moves > from left to right: > > (("a ")....) > ("a "("b ")) # match completed > > Result: $1 == "a b " > $2 == "b " > > > David > Thanks, David. It looks like this is the case. Actually, I solved my problem by using the following regexp instead: [linux.gfbs:71]gfb-ems-session_1> irb irb(main):001:0> a = "a b c d " => "a b c d " irb(main):002:0> a.scan %r{#{'(\S+\s+)' * 2}} => [["a ", "b "], ["c ", "d "]] irb(main):003:0> (My actual regexp is much bigger, I just used a simplified form for an example) Gennady.