Why doesn't the first print statement output what I expect:
first = This is a test string, sec = This is a test string
Since both * and + are greedy, why does the the inner * i.e. inside the "((" in the first match not consuming the entire string?
use strict;
use warnings;
my $string = "This is a test string";
$string =~ /((.*)*)/;
print "first = $1, sec = $2\n"; #prints "first = This is a test string, sec ="
$string =~ /((.+)*)/;
print "first = $1, sec = $2\n"; #prints "first = This is a test string, sec = This is a test string"
In the first regex .*
is matched two times. The first time it matches the whole string. The second time it matches the empty string at the end, because .*
matches the empty string when there is nothing else to match.
This does not happen with the other regex because .+
can't match the empty string.
Edit: As to what goes where: $2 will contain what is matched the last time .*
/ .+
are applied. $1 will contain what is matched by (.*)*
/ (.+)*
, i.e. the whole string.
Running it with "use re 'debug'
" results in:
Compiling REx "((.*)*)"
Final program:
1: OPEN1 (3)
3: CURLYX[0] {0,32767} (12)
5: OPEN2 (7)
7: STAR (9) # <====
8: REG_ANY (0)
9: CLOSE2 (11)
11: WHILEM[1/1] (0)
12: NOTHING (13)
13: CLOSE1 (15)
15: END (0)
minlen 0
Matching REx "((.*)*)" against "This is a test string"
0 <> <This is a > | 1:OPEN1(3)
0 <> <This is a > | 3:CURLYX[0] {0,32767}(12)
0 <> <This is a > | 11: WHILEM[1/1](0)
whilem: matched 0 out of 0..32767
0 <> <This is a > | 5: OPEN2(7)
0 <> <This is a > | 7: STAR(9) # <====
REG_ANY can match 21 times out of 2147483647...
21 < test string> <> | 9: CLOSE2(11)
21 < test string> <> | 11: WHILEM[1/1](0)
whilem: matched 1 out of 0..32767
21 < test string> <> | 5: OPEN2(7)
21 < test string> <> | 7: STAR(9) # <====
# This is where the outputs really start to diverge
# --------------------------------------------------------------------------------------------
REG_ANY can match 0 times out of 2147483647...
21 < test string> <> | 9: CLOSE2(11) # <==== Succeeded
21 < test string> <> | 11: WHILEM[1/1](0)
whilem: matched 2 out of 0..32767
whilem: empty match detected, trying continuation...
# --------------------------------------------------------------------------------------------
21 < test string> <> | 12: NOTHING(13)
21 < test string> <> | 13: CLOSE1(15)
21 < test string> <> | 15: END(0)
Match successful!
Compiling REx "((.+)*)"
Final program:
1: OPEN1 (3)
3: CURLYX[0] {0,32767} (12)
5: OPEN2 (7)
7: PLUS (9) # <====
8: REG_ANY (0)
9: CLOSE2 (11)
11: WHILEM[1/1] (0)
12: NOTHING (13)
13: CLOSE1 (15)
15: END (0)
minlen 0
Matching REx "((.+)*)" against "This is a test string"
0 <> <This is a > | 1:OPEN1(3)
0 <> <This is a > | 3:CURLYX[0] {0,32767}(12)
0 <> <This is a > | 11: WHILEM[1/1](0)
whilem: matched 0 out of 0..32767
0 <> <This is a > | 5: OPEN2(7)
0 <> <This is a > | 7: PLUS(9) # <====
REG_ANY can match 21 times out of 2147483647...
21 < test string> <> | 9: CLOSE2(11)
21 < test string> <> | 11: WHILEM[1/1](0)
whilem: matched 1 out of 0..32767
21 < test string> <> | 5: OPEN2(7)
21 < test string> <> | 7: PLUS(9) # <====
# This is where the outputs really start to diverge
# ------------------------------------------------------------------------------------
REG_ANY can match 0 times out of 2147483647...
failed... # <==== Failed
whilem: failed, trying continuation...
# ------------------------------------------------------------------------------------
21 < test string> <> | 12: NOTHING(13)
21 < test string> <> | 13: CLOSE1(15)
21 < test string> <> | 15: END(0)
Match successful!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With