从字符串开头删除字符串


Answers:


339

普通格式,不带正则表达式:

$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秒)之后。

显然,已在我的服务器上进行了分析。


8
我从未见过三元运算符被如此严重地滥用,一个简单的例子if(condition) { statement }将变得如此清晰。
塔图·乌尔曼嫩

4
@salathe:我接受批评。好奇什么是最快的。
法比奥·莫拉

51
@salathe,我不明白。提出了惯用的解决方案和基于正则表达式的解决方案:比较效率方面的两个方面有助于找到最佳的(同样是效率方面)答案。为什么那是邪恶的?
cbrandolino

5
@cbrandolino,没有人说这是邪恶的。我只是认为这与问题完全无关;就像“这里有两个解决方案,下面是一些小猫需要更多投票”的照片一样。
萨拉

5
if (substr($str, 0, strlen($prefix)) == $prefix) 可以更改为if (0 === strpos($str, $prefix))避免不必要的内存分配,同时保持相同的可读性:)
xDaizu

63

您可以使用带有脱字符号(^)的正则表达式,将匹配项锚定到字符串的开头:

$str = preg_replace('/^bla_/', '', $str);

我想知道它的运行速度是否比substr()版本快...我想是的,应该将其标记为正确答案。
Flash Thunder

除非它必须是preg_quote'd
vp_arth 18'Apr 20'18

我认为这对程序员来说不那么痛苦,而且更直观。即使它的性能比其他建议的解决方案有所下降(我真的对此表示怀疑),我还是会喜欢的。
Fr0zenFyr

multibyte噩梦是其他解决方案的另一个问题,但是如果文件的编码正确,这将很有效。无论如何,它不应该在这个问题的范围内,所以我不在乎。
Fr0zenFyr

再次提到,使用主题字符串数组还有另一个好处。substr并且strpos不能接受数组。如果您要处理数组,就可以得到明显的性能提升。干杯!
Fr0zenFyr

20
function remove_prefix($text, $prefix) {
    if(0 === strpos($text, $prefix))
        $text = substr($text, strlen($prefix)).'';
    return $text;
}

10
.''是没有必要的。
NateS 2014年

1
值得一提的是,由于每个人似乎都在这里进行了微优化,因此根据我的判断,这始终是最快的。在0.17秒内进行了1百万次迭代,而(substr($str, 0, strlen($prefix)) == $prefix)从被接受的答案
来看

5

这里。

$array = explode("_", $string);
if($array[0] == "bla") array_shift($array);
$string = implode("_", $array);

2
计时0.0000459153秒:)
Fabio Mora 2010年

速度不错,但这很难编码,具体取决于以结尾的指针_。有通用版本吗?
toddmo '18

0

我认为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),这将允许您限制从左侧开始的替换次数,但是不会强制将其开始。


1
substr_replace会替换给定范围内的字符,无论它们是您要删除的前缀还是其他名称。OP希望删除bla_“仅在字符串的开头找到它”。
Olivier'Ölbaum'Scherler '16

0

速度不错,但是很难将其编码为取决于以_结尾的指针。有通用版本吗?– toddmo 6月29日23:26

通用版本:

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

在我的旧家用PC上:

$ php bench.php

输出:

   strpos+strlen : 0.158388 s
         explode : 0.126772 s

0

这是一个更快的方法:

// strpos is faster than an unnecessary substr() and is built just for that 
if (strpos($str, $prefix) === 0) $str = substr($str, strlen($prefix));



-6

str_replace ( mixed $search , mixed $replace , mixed $subject [, int &$count ] )

现在做您想要的。

$str = "bla_string_bla_bla_bla";
str_replace("bla_","",$str,1);

7
str_replace()函数的$count参数应该是通过引用传递的变量,以包含找到的替换次数,而不是限制替换次数。
AL X

-6

删除www。从字符串开始,这是最简单的方法(ltrim)

$a="www.google.com";
echo ltrim($a, "www.");

8
第二个参数是要从字符串左侧删除的字符映射(php.net/manual/function.ltrim.php)。因此: ltrim($a, "w.");仅当域不以“ w”开头时,才可以执行此操作。ltrim ('m.google.com', ".omg")结果le.com
fragmentedreality

但它解决了问题的具体问题,+ 1
chulian

1
它确实可以解决他为回答所提出的特定问题,而不是问题的问题。即使您愿意使用ltrim,也不会正确使用它。第二个参数是应修剪的字符列表;因此,一个"w."就足够了。
fragmentedreality

我认为,恕我直言,对于问题和问题都是正确的。
abkrim

2
经过几次测试更改后,我的看法是...。在任何情况下都
无法解决
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.