Fun with perl vs php regular expression handling.
PHP has a regular expression search and replace function, preg_replace. This is supposed to be the standard greedy algorithm for patterns, for example, A* means zero or more A characters, and it matches the longest string of A's at that point.
So, if you want to match zero or more slash (/) characters at end of a string the pattern to use is: /*$
And, if we want to replace zero or more slash characters at end of a string with a single slash character, the perl code is: s!/*$!/!
Full example in perl:
foreach ('path/to', 'path/to//', 'path/to///', 'path/to////') {
my $s = $_;
$s =~ s!/*$!/!;
print "string: $_ changed to $s\n";
}
Output is:
string: path/to changed to path/to/
string: path/to// changed to path/to/
string: path/to/// changed to path/to/
string: path/to//// changed to path/to/
And the above output is all correct.
Equivalent PHP code does not work, using PHP version 5.1.6.
Following PHP code: $t = preg_replace('!/*$!', '/', $s);
fails, it will end up with one / if the input has 0 or 1 / characters, but it will end up with two / characters if the input has 2 or more / characters, instead of a single / character. So, the match was not greedy, but for reason, was split into two matches, and then each matched group was replaced with a single / character.
The workaround for this is to specify a limit count of 1 to preg_replace, which makes the code work fine. preg_match seems to work fine, only preg_replace has this problem.
Here's php code, and its output, showing the failure:
<?php
foreach (array('path/to', 'path/to//', 'path/to///', 'path/to////') as $s) {
# preg_match('!/*$!', $s, $matches); // works fine, is greedy - $matches[0] is zero or all slashes
# $t = preg_replace('!/*$!', '/', $s, 1); // works, limit of 1 helps