I was testing an example from "Mastering Regular Expressions" by Jeffrey Friedl. I don't understand the "commafication" example he gave demonstrating look ahead/behinds:
my $test1 = "the new york lotto jackpot is now 1856000 dollars";
my $test2 = "the new york lotto jackpot is now 1856000 dollars";
print "original statement: $test1\n";
$test1 =~ s/(?<=\d)(?=(\d\d\d)+)/,/g;
print "test 1: $test1\n";
$test2 =~ s/(?<=\d)(?=(\d\d\d)+(?!\d))/,/g;
print "test 2: $test2\n";
result:
original statement: the new york lotto jackpot is now 1856000 dollars
test 1: the new york lotto jackpot is now 1,8,5,6,000 dollars
test 2: the new york lotto jackpot is now 1,856,000 dollars
the goal of the regex being to insert a comma in number every 3 digits.
I don't understand the role (?!\d) plays, and why in the expression without it the lookahead groups overlap.
The first regex looks for points in the string that are preceded by a digit, and followed by a multiple of three digits.
So in 1856000, the first point that is preceded by a digit is right after the 1. Then the check that is followed by a multiple of three digits is also successful, because there is 856 and 000, so the comma is inserted.
The next point that is preceded by a digit is right after the 8, but the problem comes with a check for a multiple of three digits, because 560 is a multiple of three digits and it immediately follows this point in the string. So another comma is inserted here incorrectly.
The test should specify that the point is followed by only a multiple of three digits, so that three digits followed by two more spare digits doesn't count.
This is done here by insisting that the triplets are not followed by another digit, which is the rôle of (?!\d). Now, the point just after the 8 is correctly preceded by a digit and followed by one triplet, but the character after that triplet is another digit 0, so the pattern doesn't match until the point after 6, which has a single triplet after it, and no digit after that.
I hope this helps
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