PHP Preg-替换多个下划线

发布于 2024-08-11 02:12:10 字数 53 浏览 3 评论 0原文

如何使用 preg_replace 将多个下划线替换为一个下划线?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

凉城 2024-08-18 02:12:10

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

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

这会将一个或多个下划线替换为单个下划线。


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

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

或者用大括号编写量词:

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

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

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

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);
温暖的光 2024-08-18 02:12:10
preg_replace('/[_]+/', '_', $your_string);
preg_replace('/[_]+/', '_', $your_string);
无言温柔 2024-08-18 02:12:10

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

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.

谜泪 2024-08-18 02:12:10

运行测试,我发现这个:

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() 总是更快。

我知道有些人出于速度以外的原因更喜欢一种方法而不是另一种方法,我很高兴阅读有关结果、测试方法等的评论。

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.

倾城泪 2024-08-18 02:12:10

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

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

我不建议使用 + 因为它会进行不必要的替换(__

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

使用字符类绝对没有任何好处/[_]+//[_]{2,}/

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

For anyone attracted to @GZipp's answer for benchmark/microptimization reasons, I think the following post-test loop should execute slightly better than the pre-test while() loop because the strpos() call has been removed.

str_replace() has a reference variable parameter that can be used to break the loop without an extra, iterated function call. Granted it will always attempt to do at least one replacement, and it won't stop until after it has traversed the string with no replacements.

Code: (Demo)

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

var_export($str);
// 'one_two_three_four_bye'

As for preg_replace(), here are a couple of good options:

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

I don't recommend using + because it makes needless replacements (_ to _)

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

There is definitely no benefit to using a character class /[_]+/ or /[_]{2,}/.

The benefit of using preg_replace() is that the string is never traversed more than once. This makes it a very direct and appropriate tool.

霞映澄塘 2024-08-18 02:12:10

preg_replace()

需要 + 运算符

$text = "______";
$text = preg_replace('/[_]+/','_',$text);

preg_replace()

the + operator is needed

$text = "______";
$text = preg_replace('/[_]+/','_',$text);
人事已非 2024-08-18 02:12:10

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

pattern('_+')->replace($your_string)->with('_');

You can also use T-Regx library which has automatic delimiters.

pattern('_+')->replace($your_string)->with('_');
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文