Удалить часть строки после определенного символа

150

Мне просто интересно, как я могу удалить все после определенной подстроки в PHP

пример:

Posted On April 6th By Some Dude

Я бы хотел, чтобы он удалял весь текст, включая и после подстроки "By"

Благодарность

Белгин Фиш
источник
1
Что делать, если подстрока встречается дважды (или больше)?
Барт Кирс,
18
В качестве примечания: если вы делаете это для того, чтобы взять чужой контент и представить его на своем собственном сайте, не делайте этого .
ceejayoz
Я согласен с ceejayoz. Это очень похоже на то, как если бы вы пытались использовать контент, к которому у вас действительно нет доступа, и пытаетесь удалить любую ссылку на исходного автора. Это было бы не очень хорошо ...
selfawaresoup
2
Альтернативное отличное решение stackoverflow.com/a/9315908/1518921 :)
Guilherme Nascimento
2
На самом деле, при работе с контентом, созданным с помощью CMS, это обычное дело по уважительным причинам. Причина в том, что вы никогда не хотите связываться с реальным кодом, который создает подобный фрагмент, потому что вы нарушите свои обновления; Итак, вы позволяете ему делать свое дело, а затем делаете свое дело.
Nosajimiki

Ответы:

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

На простом английском: дайте мне часть строки, начинающуюся с начала и заканчивающуюся в позиции, где вы впервые встретили разделитель.

Остин Фицпатрик
источник
12
А как насчет «делать это только если» существует? »
Алиссо,
4
Ты прав. strpos вернет FALSE, если "By" не будет найдено. substr вернет пустую строку, если заданная длина ложна. На практике, вероятно, было бы полезно проверить, существует ли «By», и делать это только в том случае, если он существует (в противном случае просто оставив строку в покое).
Остин Фицпатрик
15
Это работает: strpos ($ variable, "By")? substr ($ variable, 0, strpos ($ variable, "By")): $ variable;
Ной Гэри
Я дал ответ, который, как мне кажется, касается всего нижеприведенного, а также объясняет способы работы со всеми видами вещей, такими как нечувствительность к регистру, множественные вхождения и регулярные выражения. Если кто-то хочет сделать что-то более гибкое или не имеет контроля над входящими данными, вероятно, стоит проверить.
azoundria
1
Идеально подходит для меня @Goahnary!
денис
107

Если вы используете PHP 5.3+, обратите внимание на флаг $ before_needle функции strstr ()

$s = 'Posted On April 6th By Some Dude';
echo strstr($s, 'By', true);
VolkerK
источник
4
Спасибо, это реальный правильный ответ в наше время !
Matmarbon
60
Обратите внимание, что он вернется, FALSEесли часть строки не найдена. Таким образом, решение может быть таким:echo strstr($s, 'By', true) ?: $s;
kenorb
7
^^^ Ответ kenorb должен быть принятым ответом сегодня. explode(' By', $s)[0]ИМХО от Squarecandy
Зак Моррис
Действительно, проверка существования kenorb - это способ сделать это, даже если это не требуется для проверки строки.
BarryMode
Просто хочу сказать, что метод @kenorb - это сиськи.
Куинн Комендант
34

Как насчет использования explode:

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

Преимущества:

квадратные конфеты
источник
@bkac - Что плохого в старомодности, если она работает и не обесценивается?
squarecandy 05
5
Это исключает дополнительную проверку существования строки разделителя, требуемую принятым ответом.
Дэвид Каллен
19

Вы могли сделать:

$posted = preg_replace('/ By.*/', '', $posted);
echo $posted;
JYelton
источник
4
+1 Это единственный, который работает, если управляющие символы НЕ присутствуют (в отличие от других, которые возвращают пустую строку, если управляющие символы отсутствуют в исходной строке)
Том Аугер
9

Один из способов:

$str = 'Posted On April 6th By Some Dude';
echo strtok($str, 'By'); // Posted On April 6th
ХАДИ
источник
Это лучший ответ, он работает, даже если By отсутствует в строке, ответ substr неверен, потому что он не работает.
neoteknic
1
Это неверно: функция будет разделена не по By, а по любому символу во втором параметре. Это означает, что он будет разделен на Bили y. Технически, это не все до By.
MSB
Будьте осторожны: 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",",");
?>
Тим Йобсон
источник
Было бы гораздо лучше назвать функцию strip_after_string вместо sas и иметь кодовую базу, полную загадочных инициализмов. Однако это мой любимый наиболее читаемый ответ на этот вопрос.
Пыльники
5

Ответ Остина работает для вашего примера.

В более общем плане вам следует изучить функции регулярных выражений, когда подстрока, которую вы разделяете, может различаться между строками:

$ variable = preg_replace ('/ By. * /', '', $ variable);
джемфинч
источник
+1, это правильно. Если вы хотите также разделить на «Автор:» или «Автор:» или «Использовано с согласия:», вероятно, проще всего будет создать регулярное выражение. Однако, когда я не использую логику регулярных выражений, я стараюсь избегать их, поскольку они, кажется, немедленно добавляют уровень сложности коду (по крайней мере, для меня),
Остин Фицпатрик,
4

Вы можете использовать listи explodeфункции:

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 в строке. Если 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
}

Поначалу регулярные выражения могут показаться запутанными, но они могут быть действительно мощными и вашими лучшими друзьями, когда вы их освоите! Удачи!

азундрия
источник
1

Зачем...

Это, вероятно, излишне для нужд большинства людей, но оно касается ряда вещей, которых нет в каждом отдельном ответе выше. Из пунктов, которые он адресовал, три из них были необходимы для моих нужд. С жесткими скобками и отбрасыванием комментариев это все еще могло оставаться читаемым всего на 13 строках кода.

Это касается следующего:

  • Влияние на производительность использования REGEX vs strrpos / strstr / strripos / stristr.
  • Использование strripos / strrpos, когда символ / строка не найдены в строке.
  • Удаление с левой или правой стороны строки (первое или последнее вхождение).
  • Чувствительность к CaSe.
  • Требуется возможность вернуть исходную строку без изменений, если поисковый символ / строка не найден.

Применение:

Отправьте исходную строку, поиск char / string, "R" / "L" для начала справа или слева, true / false для чувствительности к регистру. Например, поиск «здесь» без учета регистра в строке, начало с правой стороны.

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

Результатом будет «Вот несколько слов». Замена «R» на «L» приведет к выводу: «Сейчас».

Вот функция:

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; }
Валенте
источник