5

我如何使用preg_replace,用一个下划线替换多个下划线?

4

7 回答 7

21

+运算符(量词)匹配最后一个字符的多个实例(字符类或捕获组或反向引用)。

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

这将用一个下划线替换一个或多个下划线。


从技术上讲,对问题的标题更正确的是只替换两个或更多

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

或者用大括号写量词:

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

也许然后捕获和(返回-)参考:

$string = preg_replace('/(_)\1+/', '\1', $string);
于 2009-11-13T14:24:23.690 回答
8
preg_replace('/[_]+/', '_', $your_string);
于 2009-11-13T14:24:17.113 回答
7

运行测试,我发现了这个:

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

始终比这更快:

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

我用这个生成了不同长度的测试字符串:

$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);

并使用这些脚本进行测试(单独运行,但对于$len的每个值都使用相同的字符串):

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

和:

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

对于较短的字符串,该str_replace()方法比该preg_replace()方法快 25%。字符串越长,差异越小,但str_replace()总是更快。

我知道有些人会因为速度以外的原因更喜欢一种方法,我很乐意阅读有关结果、测试方法等的评论。

于 2009-11-13T16:22:21.993 回答
7

实际上使用/__+/or/_{2,}/会更好,/_+/因为不需要替换单个下划线。这将提高 preg 变体的速度。

于 2009-11-13T17:29:20.743 回答
2

对于因基准/微优化原因而被@GZipp 的答案吸引的任何人,我认为以下测试后循环应该比测试前循环执行得稍好,while()因为strpos()调用已被删除。

str_replace()有一个引用变量参数,可用于中断循环,而无需额外的迭代函数调用。当然,它总是会尝试至少进行一次替换,并且在遍历没有替换的字符串之前它不会停止。

代码:(演示

$str = 'one_two__three___four____bye';
do {
    $str = str_replace('__', '_', $str, $count);
} while ($count);

var_export($str);
// 'one_two_three_four_bye'

至于preg_replace(),这里有几个不错的选择:

echo preg_replace('/_{2,}/', '_', $str);
echo preg_replace('/_\K_+/', '', $str);  // \K forgets the first, remembers the rest

我不建议使用+,因为它会进行不必要的替换 ( _to _)

echo preg_replace('/_+/', '_', $str);

使用字符类/[_]+//[_]{2,}/.

使用的好处preg_replace()是字符串永远不会被遍历超过一次。这使它成为一个非常直接和合适的工具。

于 2021-08-19T13:46:08.697 回答
0

preg_replace()

需要 + 运算符

$text = "______";
$text = preg_replace('/[_]+/','_',$text);
于 2009-11-13T14:26:04.397 回答
0

您还可以使用具有自动分隔符的 T-Regx 库。

pattern('_+')->replace($your_string)->with('_');
于 2019-01-15T16:11:40.377 回答