我有一个看起来像这样的字符串:
$str = "bla_string_bla_bla_bla";
如果在字符串开头找到第一个bla_
,我该如何删除它?
使用str_replace()
会删除所有bla_
。
不使用正则表达式的普通形式:
$prefix = 'bla_';
$str = 'bla_string_bla_bla_bla';
if (substr($str, 0, strlen($prefix)) == $prefix) {
$str = substr($str, strlen($prefix));
}
需要时间:0.0369毫秒(0.000,036,954秒)
同时使用:
$prefix = 'bla_';
$str = 'bla_string_bla_bla_bla';
$str = preg_replace('/^' . preg_quote($prefix, '/') . '/', '', $str);
执行时间为:0.1749毫秒(0.000,174,999秒)第一次运行(编译),之后为0.0510毫秒(0.000,051,021秒)。
在我的服务器上进行了性能测试。
if(condition) { statement }
会清晰得多。 - Tatu Ulmanenif (substr($str, 0, strlen($prefix)) == $prefix)
改为 if (0 === strpos($str, $prefix))
,这样可以避免不必要的内存分配,同时保持可读性不变 :) - xDaizu你可以使用正则表达式中的脱字符号(^
),它将匹配锚定在字符串的开头:
$str = preg_replace('/^bla_/', '', $str);
substr()
版本更快... 我猜它是,应该标记为正确答案。 - Flash Thundersubstr
和strpos
无法接受一个数组作为参数。所以如果你需要处理一个数组,那么使用这个方法肯定会带来明显的性能提升。祝好! - Fr0zenFyrfunction remove_prefix($text, $prefix) {
if(0 === strpos($text, $prefix))
$text = substr($text, strlen($prefix)).'';
return $text;
}
(substr($str, 0, strlen($prefix)) == $prefix)
则需要大约0.37秒。 - But those new buttons though..str_starts_with()
函数来简化操作:$str = "bla_string_bla_bla_bla";
$prefix = "bla_";
if (str_starts_with($str, $prefix)) {
$str = substr($str, strlen($prefix));
}
https://www.php.net/manual/zh/function.str-starts-with.php
编辑:修正示例代码中的括号错误。
$array = explode("_", $string);
if($array[0] == "bla") array_shift($array);
$string = implode("_", $array);
explode()
,但如果你_必须_使用,那么你应该使用它的limit参数。这个答案缺少了有关教育方面的解释。 - mickmackusa这里有一个更快的方法:
// strpos is faster than an unnecessary substr() and is built just for that
if (strpos($str, $prefix) === 0) $str = substr($str, strlen($prefix));
这里有很多不同的答案,似乎都是基于字符串分析。以下是我使用PHP的explode
将字符串拆分为仅包含两个值的数组,并干净地返回第二个值的方法:
$str = "bla_string_bla_bla_bla";
$str_parts = explode('bla_', $str, 2);
$str_parts = array_filter($str_parts);
$final = array_shift($str_parts);
echo $final;
string_bla_bla_bla
$parts = explode($start, $full, 2);
if ($parts[0] === '') {
$end = $parts[1];
} else {
$fail = true;
}
<?php
$iters = 100000;
$start = "/aaaaaaa/bbbbbbbbbb";
$full = "/aaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee";
$end = '';
$fail = false;
$t0 = microtime(true);
for ($i = 0; $i < $iters; $i++) {
if (strpos($full, $start) === 0) {
$end = substr($full, strlen($start));
} else {
$fail = true;
}
}
$t = microtime(true) - $t0;
printf("%16s : %f s\n", "strpos+strlen", $t);
$t0 = microtime(true);
for ($i = 0; $i < $iters; $i++) {
$parts = explode($start, $full, 2);
if ($parts[0] === '') {
$end = $parts[1];
} else {
$fail = true;
}
}
$t = microtime(true) - $t0;
printf("%16s : %f s\n", "explode", $t);
$ php bench.php
输出:
strpos+strlen : 0.158388 s
explode : 0.126772 s
Symfony用户可以安装字符串组件并使用trimPrefix()
u('file-image-0001.png')->trimPrefix('file-'); // 'image-0001.png'
我认为substr_replace可以满足您的需求,您可以将替换限制在字符串的一部分中: http://nl3.php.net/manual/en/function.substr-replace.php(这将使您只查看字符串的开头。)
您可以使用str_replace的count参数(http://nl3.php.net/manual/en/function.str-replace.php),这将允许您从左侧开始限制替换次数,但它不会强制其位于开头。
substr_replace
将替换给定范围内的字符,无论它们是您想要删除的前缀还是其他内容。 OP 希望仅在字符串开头找到 bla_
时才删除它。 - Olivier 'Ölbaum' Scherlerstr_replace()
的计数参数并不能让你限制替换的次数。 - mickmackusa
s($str)->replacePrefix('_bla')
很有用,它可以在这个独立库中找到。 - caw