【问题标题】:Remove portion of a string after a certain character在某个字符之后删除字符串的一部分
【发布时间】:2020-11-23 11:35:49
【问题描述】:

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

例如:

Posted On April 6th By Some Dude

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

谢谢

【问题讨论】:

标签: php string


【解决方案1】:
$variable = substr($variable, 0, strpos($variable, "By"));

用简单的英语:给我从开头到你第一次遇到分隔符的位置结束的字符串部分。

【讨论】:

  • “只有在“by”存在的情况下才这样做呢?
  • 你是对的。如果未找到“By”,strpos 将返回 FALSE。如果给定的长度为假,substr 将返回一个空字符串。在实践中,检查“B​​y”是否存在可能会很有用,然后仅在存在时才执行此操作(否则只保留字符串)。
  • 我提出了一个答案,我认为该答案解决了以下所有问题,并解释了处理各种问题的方法,例如不区分大小写、多次出现和正则表达式。如果有人想做更灵活的事情或无法控制输入,那么可能值得一试。
  • 如果我要删除所有内容之后的字符串是“\n”怎么办。我试过: $skill_current = substr($skill_current, 0, strpos($skill_current, "\n"));我试过 $skill_current = substr($skill_current, 0, strpos($skill_current, "\\n")); - 没用
  • \public static function removeContentAfter(string $string, string $after): string { return false !== ($pos = strpos($string, $after)) ? substr($string, 0, $pos) : $string; } 如果未找到“By”,则返回原件
【解决方案2】:

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

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

【讨论】:

  • 请注意,如果未找到部分字符串,它将返回FALSE。所以解决方案可能是:echo strstr($s, 'By', true) ?: $s;
  • kenorb 的评论解决方案不是防弹的。当返回的子字符串为 falsey 时会失败。证明:3v4l.org/4kYeU
【解决方案3】:

explode怎么样:

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

优点:

【讨论】:

  • @bkac - 只要能正常工作且不折旧,老式有什么问题?
  • 这消除了对接受的答案所需的分隔符字符串是否存在的额外检查。
  • 不需要对字符串中的all By 子字符串进行分解,因此explode() 调用应包含2 的限制参数。使用explode() 的缺点是您需要在隔离所需字符串的过程中生成一个临时数组。
  • 这是一个关于添加限制参数的好点。我认为,如果您正在处理一个相当可预测的数据集,那么这并不重要——就像在示例中,如果它总是“在 {date} 上由 {name} 发布”。但是,是的,添加两个限制是一个很好的健全性检查。如果名称是“Byron Byronson”或其他名称,它还会使作者姓名在 $result[1] 中仍然可用。在生成不必要的数组方面 - 我认为速度和代码可读性与使用基于正则表达式的函数相比是值得的。
【解决方案4】:

你可以这样做:

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

这是一个正则表达式替换函数,它查找文字字符串“ By”及其后面的任意数量的字符 (.*),并将它们替换为空字符串 (''),并将结果存储在搜索的相同变量 ($posted)。

如果在输入字符串中没有找到[space]By,则字符串保持不变。

【讨论】:

    【解决方案5】:

    一种方法是:

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

    【讨论】:

    • 这是最好的答案,即使 By 不在字符串中,substr 答案是错误的,因为它不存在,它失败了。
    • 这是不正确的:函数不会被By分割,而是被第二个参数中的任何字符分割。意思是,它将被By 分割。从技术上讲,它并没有在By 之前得到一切。
    • 注意:如果字符串中的第一个字符,strtok 将返回字符串之后字符的部分,例如strtok('a:b', ':') 将返回a 但是strtok(':b', ':') 将返回 b,而不是您期望的空字符串。
    【解决方案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",",");
    ?>
    

    【讨论】:

      【解决方案7】:

      Austin 的回答适用于您的示例案例。

      更一般地说,当您要拆分的子字符串在字符串之间可能不同时,您最好查看regular expression functions

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

      【讨论】:

        【解决方案8】:

        您可以使用listexplode 函数:

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

        【讨论】:

          【解决方案9】:
          $var = "Posted On April 6th By Some Dude";
          $new_var = substr($var, 0, strpos($var, " By"));
          

          【讨论】:

          • 这个无法解释的答案与接受的答案存在相同的漏洞,因为没有明确的=== false 检查。当没有找到针时,整个字符串被截断。我希望看到整个输入字符串,但我得到一个长度为零的字符串。 3v4l.org/f7ue2
          【解决方案10】:

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

          【讨论】:

          • 请在这个纯代码答案中包含一些解释。
          • 不需要字符串元字符$ 的结尾。零个或多个量词将转到字符串的末尾。
          【解决方案11】:

          以下是最有效的方法(按运行时),可以切断字符串中第一个 By 之后的所有内容。如果 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);
          

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

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

          正则表达式起初可能看起来令人困惑,但一旦你掌握了它们,它们就会变得非常强大并且是你最好的朋友!祝你好运!

          【讨论】:

            【解决方案12】:

            preg_replace 提供一种方式:

            $newText = preg_replace('/\bBy\b.*$/', '', $text);
            

            '\b' 在单词边界上匹配(它是零宽度并且匹配单词和非单词字符),确保它只会匹配一个完整的单词。虽然目标词在示例中不会作为任何其他词的一部分出现,但通常目标可能会作为另一个词的一部分出现(例如“'Babylon Revisited', by F. Scott Fitzgerald”或“' Berkely Breathed 的《布卢姆县巴比伦》)。

            '.*$' 匹配所有文本直到最后。 '$' 匹配字符串的结尾,虽然对于正确性不是绝对必要的,但它记录了正则表达式的意图(众所周知,它变得难以阅读)。

            正则表达式匹配从字符串的开头开始,所以这将替换从第一个匹配开始。如何改为从最后开始匹配,请参阅“How to replace only the last match of a string with preg_replace?

            【讨论】:

            • 对该模式的作用以及为什么它是一个好主意的一些解释将使这个答案对研究人员更有帮助。或许可以解释为什么这个答案优于此页面上发布的其他技术。
            【解决方案13】:

            为什么...

            对于大多数人的需求来说,这可能是多余的,但是,它解决了上面每个人的答案都没有解决的许多问题。在它解决的项目中,其中三个是我需要的。通过严格的括号和删除 cmets,这仍然可以仅用 13 行代码保持可读性。

            这解决了以下问题:

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

            用法:

            发送原始字符串,搜索字符/字符串,“R”/“L”表示右侧或左侧开始,true/false 区分大小写。例如,搜索“这里”不区分大小写,在字符串中,从右侧开始。

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

            输出将是“Now Here Are Some Words”。将“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
                }           
            
            }
            

            【讨论】:

            • 如果您对我的工作答案投反对票,我们将不胜感激您说明原因。
            • strstr() 页面上的 php 手册中有一个特定的注释指出:“如果您只想确定某个特定的针是否出现在 haystack 中,请使用更快且更少的内存而是使用强化函数 strpos()。" php.net/manual/en/function.strstr (我没有给出这个答案,但我看到了一些赋值声明,我认为您打算在其中检查 $startSide 是否松散地等于零长度字符串。 )
            • @mickmackusa 谢谢。我使用 strstr() 来避免处理不同类型的返回字符串(布尔值和整数,取决于)所需的额外处理,并确保既不将 0 作为第一个字符处理,也不将 true 作为第二个字符处理。下周我会再看一次,看看我能做出什么改变。非常感谢您对 DV 的投入和推迟!!!
            【解决方案14】:

            使用strstr 函数。

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

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

            【讨论】:

            • strtok($str, 'By') 看起来更简单
            • strstr() 并不总是返回字符串。
            【解决方案15】:

            嘿,我认为这对于想要替换 “By”之后的字符的人可能有用,例如在他给出的文本中,他在 20th > 他的字符串的位置,所以如果你想忽略 by 你应该 add + 2 到那个位置,然后它会忽略第 20 个位置,它会在出现后替换所有如果您提供要替换的文本的确切字符长度,它将起作用

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

            【讨论】:

            • 这个答案与接受的答案犯了同样的错误,因为它没有明确检查strpos()是否返回false(相对于0)。
            【解决方案16】:
            $variable = substr($initial, 0, strpos($initial, "By"));
            
            if (!empty($variable)) { echo $variable; } else { echo $initial; }
            

            【讨论】:

            • 这个无法解释的答案与接受的答案犯的错误相同,因为它没有明确检查strpos() 是否返回false(相对于0)。更糟糕的是,这个答案再次对从substr() 返回的字符串进行错误检查,这也可能导致错误的结果。这个答案没有什么值得保留的。
            猜你喜欢
            • 2017-02-26
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-03-02
            相关资源
            最近更新 更多