Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP Preg-Replace more than one underscore

How do I, using preg_replace, replace more than one underscore with just one underscore?

like image 601
somejkuser Avatar asked Nov 13 '09 14:11

somejkuser


4 Answers

The + operator (quantifier) matches multiple instances of the last character (, character class or capture group or back-reference).

$string = preg_replace('/_+/', '_', $string);

This would replace one or more underscores with a single underscore.


Technically more correct to the title of the question then is to only replace two or more:

$string = preg_replace('/__+/', '_', $string);

Or writing the quantifier with braces:

$string = preg_replace('/_{2,}/', '_', $string);

And perhaps then to capture and (back-) reference:

$string = preg_replace('/(_)\1+/', '\1', $string);
like image 52
soulmerge Avatar answered Oct 04 '22 05:10

soulmerge


preg_replace('/[_]+/', '_', $your_string);
like image 29
chelmertz Avatar answered Oct 04 '22 04:10

chelmertz


Actually using /__+/ or /_{2,}/ would be better than /_+/ since a single underscore does not need to be replaced. This will improve the speed of the preg variant.

like image 45
Cheatah Avatar answered Oct 04 '22 04:10

Cheatah


Running tests, I found this:

while (strpos($str, '__') !== false) {
    $str = str_replace('__', '_', $str);
}

to be consistently faster than this:

$str = preg_replace('/[_]+/', '_', $str);

I generated the test strings of varying lengths with this:

$chars = array_merge(array_fill(0, 50, '_'), range('a', 'z'));
$str = '';
for ($i = 0; $i < $len; $i++) {  // $len varied from 10 to 1000000
    $str .= $chars[array_rand($chars)];
}
file_put_contents('test_str.txt', $str);

and tested with these scripts (run separately, but on identical strings for each value of $len):

$str = file_get_contents('test_str.txt');
$start = microtime(true);
$str = preg_replace('/[_]+/', '_', $str);
echo microtime(true) - $start;

and:

$str = file_get_contents('test_str.txt');
$start = microtime(true);
while (strpos($str, '__') !== false) {
    $str = str_replace('__', '_', $str);
}
echo microtime(true) - $start;

For shorter strings the str_replace() method was as much as 25% faster than the preg_replace() method. The longer the string, the less the difference, but str_replace() was always faster.

I know some would prefer one method over the other for reasons other than speed, and I'd be glad to read comments regarding the results, testing method, etc.

like image 44
GZipp Avatar answered Oct 04 '22 04:10

GZipp