从字符串的开头删除字符串

发布于 2024-10-08 18:58:06 字数 203 浏览 3 评论 0原文

我有一个如下所示的字符串:

$str = "bla_string_bla_bla_bla";

如何删除第一个 bla_;但前提是它是在字符串的开头找到的?

使用str_replace(),它会删除所有 bla_

I have a string that looks like this:

$str = "bla_string_bla_bla_bla";

How can I remove the first bla_; but only if it's found at the beginning of the string?

With str_replace(), it removes all bla_'s.

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

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

发布评论

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

评论(11

忘羡 2024-10-15 18:58:06

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

$prefix = 'bla_';
$str = 'bla_string_bla_bla_bla';

if (substr($str, 0, strlen($prefix)) == $prefix) {
    $str = substr($str, strlen($prefix));
} 

需要:0.0369 ms(0.000,036,954 秒)

并且:

$prefix = 'bla_';
$str = 'bla_string_bla_bla_bla';
$str = preg_replace('/^' . preg_quote($prefix, '/') . '/', '', $str);

第一次运行(编译)需要:0.1749 ms(0.000,174,999 秒),以及之后的 0.0510 毫秒(0.000,051,021 秒)。

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

Plain form, without regex:

$prefix = 'bla_';
$str = 'bla_string_bla_bla_bla';

if (substr($str, 0, strlen($prefix)) == $prefix) {
    $str = substr($str, strlen($prefix));
} 

Takes: 0.0369 ms (0.000,036,954 seconds)

And with:

$prefix = 'bla_';
$str = 'bla_string_bla_bla_bla';
$str = preg_replace('/^' . preg_quote($prefix, '/') . '/', '', $str);

Takes: 0.1749 ms (0.000,174,999 seconds) the 1st run (compiling), and 0.0510 ms (0.000,051,021 seconds) after.

Profiled on my server, obviously.

后来的我们 2024-10-15 18:58:06

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

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

You can use regular expressions with the caret symbol (^) which anchors the match to the beginning of the string:

$str = preg_replace('/^bla_/', '', $str);
贱贱哒 2024-10-15 18:58:06
function remove_prefix($text, $prefix) {
    if(0 === strpos($text, $prefix))
        $text = substr($text, strlen($prefix)).'';
    return $text;
}
function remove_prefix($text, $prefix) {
    if(0 === strpos($text, $prefix))
        $text = substr($text, strlen($prefix)).'';
    return $text;
}
沫尐诺 2024-10-15 18:58:06

在 PHP 8+ 中,我们可以使用 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/en/function.str-starts-with.php

编辑:修复了示例代码中的拼写错误(右括号)。

In PHP 8+ we can simplify using the str_starts_with() function:

$str = "bla_string_bla_bla_bla";
$prefix = "bla_";
if (str_starts_with($str, $prefix)) {
  $str = substr($str, strlen($prefix));
}

https://www.php.net/manual/en/function.str-starts-with.php

EDIT: Fixed a typo (closing bracket) in the example code.

可是我不能没有你 2024-10-15 18:58:06

这是一种更快的方法:

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

Here's an even faster approach:

// strpos is faster than an unnecessary substr() and is built just for that 
if (strpos($str, $prefix) === 0) $str = substr($str, strlen($prefix));
-黛色若梦 2024-10-15 18:58:06

这里。

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

Here.

$array = explode("_", $string);
if($array[0] == "bla") array_shift($array);
$string = implode("_", $array);
剩余の解释 2024-10-15 18:58:06

速度不错,但是这是硬编码的,取决于以 _ 结尾的针。有通用版吗? – 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);

在我相当旧的家用电脑上:

$ php bench.php

输出:

   strpos+strlen : 0.158388 s
         explode : 0.126772 s

Nice speed, but this is hard-coded to depend on the needle ending with _. Is there a general version? – toddmo Jun 29 at 23:26

A general version:

$parts = explode($start, $full, 2);
if ($parts[0] === '') {
    $end = $parts[1];
} else {
    $fail = true;
}

Some benchmarks:

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

On my quite old home PC:

$ php bench.php

Outputs:

   strpos+strlen : 0.158388 s
         explode : 0.126772 s
半边脸i 2024-10-15 18:58:06

这里有很多不同的答案。所有这些似乎都是基于字符串分析。这是我对此的看法,使用 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

Lots of different answers here. All seemingly based on string analysis. Here is my take on this using PHP explode to break up the string into an array of exactly two values and cleanly returning only the second value:

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

Output will be:

string_bla_bla_bla
仙气飘飘 2024-10-15 18:58:06

Symfony 用户可以安装字符串组件并使用trimPrefix()

u('file-image-0001.png')->trimPrefix('file-');           // 'image-0001.png'

Symfony users can install the string component and use trimPrefix()

u('file-image-0001.png')->trimPrefix('file-');           // 'image-0001.png'
木有鱼丸 2024-10-15 18:58:06

我通常对需要 3 个函数调用或生成和数组来生成字符串(而单个正则表达式函数即可完成)的技术没有兴趣。

我想提一下,如果您使用 preg_quote() 的默认掩码中包含的模式分隔符,那么您不需要指定第二个参数(# 是这些字符之一)。

文档: https://www.php.net/manual/en/ function.preg-quote.php

特殊的正则表达式字符是: . \ + * ? [ ^ ] $ ( ) {
} = ! < > | :-#

请注意,/ 不是特殊的正则表达式字符。

代码:(演示

$str = preg_replace('#^' . preg_quote($prefix) . '#'), '', $str);

为了完整起见,我想在此页面添加 sscanf() 就可以是一种合适的技术。在提问者的示例输入中,输入字符串中没有空格,因此 %s 就足够了。如果前缀后面的子字符串中有任何空格,那么 %s 就不好了——您可以使用带有不会出现的字符的否定表达式,如 %[^~]< /code> 或类似的。如果需要,此技术将通过引用修改输入字符串。 (演示

sscanf($str, "$prefix%s", $str);

我承认 sscanf() 不是最直观的用于此任务的工具,并且在某些情况下它不适合,但对于所呈现的任务,单个函数调用可以按需要工作。对于前缀后跟数字的情况,格式参数中带有 %dsscanf() 会将匹配的字符串自动转换为整数。因此,在某些情况下,它可能比 preg_ 函数调用更理想。

I generally don't have an appetite for techniques that need 3 function calls or generate and array to produce a string when a single regex function will do.

I want to mention that if you use pattern delimiters that are covered in the default mask of preg_quote(), then you won't need to nominate the second parameter (# is one of those characters).

Documenation: https://www.php.net/manual/en/function.preg-quote.php

The special regular expression characters are: . \ + * ? [ ^ ] $ ( ) {
} = ! < > | : - #

Note that / is not a special regular expression character.

Code: (Demo)

$str = preg_replace('#^' . preg_quote($prefix) . '#'), '', $str);

For completeness, I want to add to this page that sscanf() can be a suitable technique so long as you are in "control" of the prefix string and can confidently assign all characters after the prefix to a placeholder. In the asker's sample input, there are no spaces in the input string, so %s will suffice. If there are any spaces in the substring after the prefix, then %s is no good -- you might use a negated expression with a character that will not occur like %[^~] or similar. This technique will modify the input string by reference if needed. (Demo)

sscanf($str, "$prefix%s", $str);

I'll admit that sscanf() isn't the most intuitive tool for this task and there are scenarios where it is unsuitable, but for the presented task the single function call works as desired. For cases when you have a prefix followed by a number, sscanf() with %d in the format parameter will auto-cast the matched string as an integer. So there may be some scenarios where it is more ideal than a preg_ function call.

骑趴 2024-10-15 18:58:06

我认为 substr_replace 可以满足您的需求,您可以将替换限制为字符串的一部分:
https://www.php.net/manual/en/function。 substr-replace.php (这将使您只能查看字符串的开头。)

您可以使用 str_replace 的 count 参数( https://www.php.net/manual/en/function.str-replace.php ),这将允许您限制替换的数量,从左边开始,但不会强制它在开头。

I think substr_replace does what you want, where you can limit your replace to part of your string:
https://www.php.net/manual/en/function.substr-replace.php (This will enable you to only look at the beginning of the string.)

You could use the count parameter of str_replace ( https://www.php.net/manual/en/function.str-replace.php ), this will allow you to limit the number of replacements, starting from the left, but it will not enforce it to be at the beginning.

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