Reputation: 28071
"111".gsub(/1?/, "2")
=> "2222"
"111".gsub(/1/, "2")
=> "222"
"111".gsub(/1*/, "2")
=> "22"
"111".gsub(/1+/, "2")
=> "2"
Why, and how, does it work like above?
Upvotes: 2
Views: 515
Reputation: 15954
After each successful match, the part of string after the match is scanned for more matches. This is even done for an empty string (if it is not already part of the previous match).
Note also that ?
, *
and +
always match as many characters as possible ("greedy").
In detail:
"111".gsub(/1?/, "2")
The first 1
matches -> one 2
, the second and the third 1
result in two more 2
s.
Then the empty string matches, resulting in one more 2
.
"111".gsub(/1/, "2")
This is obvious.
"111".gsub(/1*/, "2")
111
matches resulting in one 2
. Then, the empty string matches resulting in one more 2
.
"111".gsub(/1+/, "2")
111
matches -> one 2
. The empty string does not match, no more 2
.
Upvotes: 2
Reputation: 77454
The first regexp matches 4 times: once on each 1
, and once on the empty string at the end.
The second regexp matches 3 times, only for the 1
s.
The third regexp matches once for 111
(greedy!) and once for the empty string at the end (*
says optional, so the empty string matches, too!)
The fourth regexp greedly takes the full string, matches only once in total. The end does not match, as there is no (required) 1
left anymore.
You should look up the notion of greedy matching with regular expressions. Here are some more for you to try: /1*?/
and /1+?/
. Figure out why these match as they do for yourself!
Upvotes: 5