删除某个字符后的字符串部分


144

我只是想知道如何在PHP中某个子字符串之后删除所有内容

例如:

Posted On April 6th By Some Dude

我想要它,以便它删除包括子字符串“ By”在内的所有文本。

谢谢


1
如果子字符串出现两次(或更多次)怎么办?
巴特·基尔斯

18
请注意,如果您正在执行此操作,则可以获取他人的内容并将其呈现在自己的网站上,请不要这样做
ceejayoz'4

我同意ceejayoz。这听起来很像是您在尝试使用您实际上无权访问的内容,并且试图删除对原始作者的任何引用。那不是很好...
selfawaresoup 2010年


1
实际上,在处理由CMS生成的内容时,出于正当的理由需要执行此类操作。原因是您永远不想弄乱创建这样的代码片段的实际代码,因为您将破坏更新。所以,你让它做自己的事,然后你做你的事。
Nosajimiki

Answers:


292
$variable = substr($variable, 0, strpos($variable, "By"));

用简单的英语来说:给我字符串的一部分,从开始到结束,直到您第一次遇到分支的位置。


11
那“只有在“ by”存在的情况下才这样做吗?
Alisso 2013年

3
你是对的。如果未找到“按”,则strpos将返回FALSE。如果给定的长度为false,substr将返回一个空字符串。在实践中,检查“ By”是否存在然后仅在存在的情况下进行检查(否则仅保留字符串)可能会很有用。
奥斯汀·菲茨帕特里克

13
这有效:strpos($ variable,“ By”)?substr($ variable,0,strpos($ variable,“ By”)):$ variable;
诺亚·加里

我给出了一个我认为可以解决所有问题的答案,并解释了处理诸如大小写不敏感,多次出现和正则表达式之类的各种问题的方法。如果有人想做任何更灵活的事情或无法控制输入的内容,那么值得一试。
azoundria

1
对我来说很完美@Goahnary!
丹尼斯

106

如果您使用的是PHP 5.3+,请查看strstr()的$ before_needle标志

$s = 'Posted On April 6th By Some Dude';
echo strstr($s, 'By', true);

4
谢谢,这是当今的正确答案!
Matmarbon 2014年

59
请注意,FALSE如果找不到字符串的一部分,它将返回。因此,解决方案可能是:echo strstr($s, 'By', true) ?: $s;
kenorb

6
kenorb的答案应该是今天公认的答案。另一个选择是Squarecandy的explode(' By', $s)[0]恕我直言
Zack Morris

确实,kenorb的存在性检查是做到这一点的方法,即使不需要测试字符串也是如此。
BarryMode

只是在这里说@kenorb的方法是山雀。
奎因·康梅登

32

如何使用explode

$input = 'Posted On April 6th By Some Dude';
$result = explode(' By',$input);
return $result[0];

优点:


@bkac-老式的只要能工作且不贬值,怎么了?
2016年

3
这消除了对接受答案所需的分隔符字符串是否存在的额外检查。
David Cullen

17

您可以这样做:

$posted = preg_replace('/ By.*/', '', $posted);
echo $posted;

4
+1这是唯一一个不存在控制字符的方法(不同于其他字符,如果源字符串中不存在控制字符则返回空字符串)
Tom Auger 2015年

9

一种方法是:

$str = 'Posted On April 6th By Some Dude';
echo strtok($str, 'By'); // Posted On April 6th

即使By不在字符串中,这也是最好的答案,substr答案是错误的,因为不存在它会失败。
neoteknic

这是不正确的:函数不会被分割By,而是被第二个参数中的任何字符分割。意思是,它将被B或分割y。从技术上讲,它不能在之前得到所有东西By
msb

注意:如果strtok是字符串中的第一个字符,则strtok将返回字符串的部分,例如,strtok('a:b', ':')将返回,astrtok(':b', ':')将返回b,而不是您期望的空字符串。
Quinn Comendant

6

试试这个。

function strip_after_string($str,$char)
    {
        $pos=strpos($str,$char);    
        if ($pos!==false) 
        {
            //$char was found, so return everything up to it.
            return substr($str,0,$pos);
        } 
        else 
        {
            //this will return the original string if $char is not found.  if you wish to return a blank string when not found, just change $str to ''
            return $str; 
        }
    }

用法:

<?php
    //returns Apples
    $clean_string= strip_after_string ("Apples, Oranges, Banannas",",");
?>

您最好将函数命名为strip_after_string而不是sas,并使代码库充满隐秘的初始化。这是我最喜欢这个问题的最易读的答案。
花药

5

奥斯汀的答案适用于您的案例。

更一般而言,当要拆分的子字符串在字符串之间可能不同时,您最好查看正则表达式函数

$ variable = preg_replace('/ By。* /','',$ variable);

+1,这是正确的。如果您还想分割“作者:”或“作者:”或“经以下人同意使用”,则进行正则表达式可能最简单。但是,当我不执行任何正则表达式逻辑时,我倾向于避免使用它们,因为它们似乎立即增加了代码的复杂度(至少对我而言)
Austin Fitzpatrick

4

您可以使用listexplode功能:

list($result) = explode("By", "Posted On April 6th By Some Dude", 2);
// $result is "Posted On April 6th "

这是最准确的。我希望我能两次投票给我
约翰·马克斯,

4
$var = "Posted On April 6th By Some Dude";
$new_var = substr($var, 0, strpos($var, " By"));


2

通过使用正则表达式: $string = preg_replace('/\s+By.*$/', '', $string)


请在此仅代码的答案中包含一些说明。
mickmackusa

2

下面是最有效的方法(按运行时),用于切断字符串中第一个“ 按”之后的所有内容。如果By不存在,则返回完整的字符串。结果在$ sResult中。

$sInputString = "Posted On April 6th By Some Dude";
$sControl = "By";

//Get Position Of 'By'
$iPosition = strpos($sInputString, " ".$sControl);
if ($iPosition !== false)
  //Cut Off If String Exists
  $sResult = substr($sInputString, 0, $iPosition);
else
  //Deal With String Not Found
  $sResult = $sInputString;

//$sResult = "Posted On April 6th"

如果不想区分大小写,请使用stripos而不是strpos。如果您认为By可能不止一次存在,并且想在最后一次出现后削减所有内容,请使用strrpos

下面是一种效率较低的方法,但是它占用的代码空间更少。此方法也更灵活,可以执行任何正则表达式。

$sInputString = "Posted On April 6th By Some Dude";
$pControl = "By";

$sResult = preg_replace("' ".$pControl.".*'s", '', $sInputString);

//$sResult = "Posted On April 6th"

例如,如果您想在一天后删除所有内容:

$sInputString = "Posted On April 6th By Some Dude";
$pControl = "[0-9]{1,2}[a-z]{2}"; //1 or 2 numbers followed by 2 lowercase letters.

$sResult = preg_replace("' ".$pControl.".*'s", '', $sInputString);

//$sResult = "Posted On April"

对于不区分大小写的情况,请添加i修饰符,如下所示:

$sResult = preg_replace("' ".$pControl.".*'si", '', $sInputString);

使所有内容都超过最后一个如果您认为可能不止一个,请在开头添加一个额外的。*,如下所示:

$sResult = preg_replace("'.* ".$pControl.".*'si", '', $sInputString);

但是,这也是一种非常强大的方法,您可以使用preg_match来执行可能要执行的操作:

$sInputString = "Posted On April 6th By Some Dude";

$pPattern = "'Posted On (.*?) By (.*?)'s";
if (preg_match($pPattern, $sInputString, $aMatch)) {
  //Deal With Match
  //$aMatch[1] = "April 6th"
  //$aMatch[2] = "Some Dude"
} else {
  //No Match Found
}

一开始,正则表达式可能看起来令人困惑,但是一旦掌握了它们,它们就可以真正强大起来,成为您最好的朋友!祝好运!


1

为什么...

对于大多数人的需求而言,这可能是多余的,但是,它解决了上面每个答案都不能解决的许多问题。在它处理的项目中,我需要其中三个。通过使用尖括号括起来并删除注释,仅需13行代码仍然可以阅读。

这解决了以下问题:

  • 使用REGEX对strrpos / strstr / strripos / stristr的性能影响。
  • 在字符串中找不到字符/字符串时,使用strripos / strrpos。
  • 从字符串的左侧或右侧删除(第一次或最后一次出现)。
  • CaSe灵敏度。
  • 如果找不到搜索字符/字符串,希望能够返回原字符串不变。

用法:

发送原始字符串,搜索字符/字符串,“ R” /“ L”表示从右侧或左侧开始,true / false表示区分大小写。例如,搜索不区分大小写的“ here”(以字符串开头)。

echo TruncStringAfterString("Now Here Are Some Words Here Now","here","R",false);

输出将是“现在有一些单词”。将“ R”更改为“ L”将输出:“ Now”。

功能如下:

function TruncStringAfterString($origString,$truncChar,$startSide,$caseSensitive)
{
    if ($caseSensitive==true && strstr($origString,$truncChar)!==false)
    {
        // IF START RIGHT SIDE:
        if (strtoupper($startSide)=="R" || $startSide==false)
        {   // Found, strip off all chars from truncChar to end
            return substr($origString,0,strrpos($origString,$truncChar));
        }

        // IF START LEFT SIDE: 
        elseif (strtoupper($startSide)=="L" || $startSide="" || $startSide==true)
        {   // Found, strip off all chars from truncChar to end
            return strstr($origString,$truncChar,true);
        }           
    }
    elseif ($caseSensitive==false && stristr($origString,$truncChar)!==false)
    {           
        // IF START RIGHT SIDE: 
        if (strtoupper($startSide)=="R" || $startSide==false)
        {   // Found, strip off all chars from truncChar to end
            return substr($origString,0,strripos($origString,$truncChar));
        }

        // IF START LEFT SIDE: 
        elseif (strtoupper($startSide)=="L" || $startSide="" || $startSide==true)
        {   // Found, strip off all chars from truncChar to end
            return stristr($origString,$truncChar,true);
        }
    }       
    else
    {   // NOT found - return origString untouched
        return $origString;     // Nothing to do here
    }           

}

如果您对我的工作答案不满意,请说明原因。
罗伯特·毛罗

0

使用strstr函数。

<?php
$myString = "Posted On April 6th By Some Dude";
$result = strstr($myString, 'By', true);

echo $result ;

第三个参数true告诉函数在第二个参数第一次出现之前返回所有内容。


1
strtok($str, 'By')看起来更简单
mu3

-2
$variable = substr($initial, 0, strpos($initial, "By"));

if (!empty($variable)) { echo $variable; } else { echo $initial; }
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.