Lai Yu-Hsuan
Lai Yu-Hsuan

Reputation: 28071

How does gsub work with '*', '+' and '?'

"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

Answers (2)

undur_gongor
undur_gongor

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 2s. 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

Has QUIT--Anony-Mousse
Has QUIT--Anony-Mousse

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 1s.

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

Related Questions