Что делать, если подстрока встречается дважды (или больше)?
Барт Кирс,
18
В качестве примечания: если вы делаете это для того, чтобы взять чужой контент и представить его на своем собственном сайте, не делайте этого .
ceejayoz
Я согласен с ceejayoz. Это очень похоже на то, как если бы вы пытались использовать контент, к которому у вас действительно нет доступа, и пытаетесь удалить любую ссылку на исходного автора. Это было бы не очень хорошо ...
На самом деле, при работе с контентом, созданным с помощью CMS, это обычное дело по уважительным причинам. Причина в том, что вы никогда не хотите связываться с реальным кодом, который создает подобный фрагмент, потому что вы нарушите свои обновления; Итак, вы позволяете ему делать свое дело, а затем делаете свое дело.
А как насчет «делать это только если» существует? »
Алиссо,
4
Ты прав. strpos вернет FALSE, если "By" не будет найдено. substr вернет пустую строку, если заданная длина ложна. На практике, вероятно, было бы полезно проверить, существует ли «By», и делать это только в том случае, если он существует (в противном случае просто оставив строку в покое).
Я дал ответ, который, как мне кажется, касается всего нижеприведенного, а также объясняет способы работы со всеми видами вещей, такими как нечувствительность к регистру, множественные вхождения и регулярные выражения. Если кто-то хочет сделать что-то более гибкое или не имеет контроля над входящими данными, вероятно, стоит проверить.
azoundria
1
Идеально подходит для меня @Goahnary!
денис
107
Если вы используете PHP 5.3+, обратите внимание на флаг $ before_needle функции strstr ()
$s = 'Posted On April 6th By Some Dude';
echo strstr($s, 'By', true);
Regex медленнее, чем Explode (я предполагаю, что preg_split аналогичен по скорости другим параметрам регулярного выражения, предложенным в других ответах)
Делает доступной и вторую часть строки, если она вам нужна ( $result[1]вернется Some Dudeв этом примере)
+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
Попробуй это.
functionstrip_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
Ответ Остина работает для вашего примера.
В более общем плане вам следует изучить функции регулярных выражений, когда подстрока, которую вы разделяете, может различаться между строками:
+1, это правильно. Если вы хотите также разделить на «Автор:» или «Автор:» или «Использовано с согласия:», вероятно, проще всего будет создать регулярное выражение. Однако, когда я не использую логику регулярных выражений, я стараюсь избегать их, поскольку они, кажется, немедленно добавляют уровень сложности коду (по крайней мере, для меня),
Пожалуйста, включите некоторые пояснения в этот ответ, состоящий только из кода.
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 следующим образом:
Но вот еще один действительно эффективный способ использования 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
}
Поначалу регулярные выражения могут показаться запутанными, но они могут быть действительно мощными и вашими лучшими друзьями, когда вы их освоите! Удачи!
Это, вероятно, излишне для нужд большинства людей, но оно касается ряда вещей, которых нет в каждом отдельном ответе выше. Из пунктов, которые он адресовал, три из них были необходимы для моих нужд. С жесткими скобками и отбрасыванием комментариев это все еще могло оставаться читаемым всего на 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» приведет к выводу: «Сейчас».
Вот функция:
functionTruncStringAfterString($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 endreturn 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 endreturn 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 endreturn 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 endreturn stristr($origString,$truncChar,true);
}
}
else
{ // NOT found - return origString untouchedreturn $origString; // Nothing to do here
}
}
Ответы:
$variable = substr($variable, 0, strpos($variable, "By"));
На простом английском: дайте мне часть строки, начинающуюся с начала и заканчивающуюся в позиции, где вы впервые встретили разделитель.
источник
Если вы используете PHP 5.3+, обратите внимание на флаг $ before_needle функции strstr ()
$s = 'Posted On April 6th By Some Dude'; echo strstr($s, 'By', true);
источник
FALSE
если часть строки не найдена. Таким образом, решение может быть таким:echo strstr($s, 'By', true) ?: $s;
explode(' By', $s)[0]
ИМХО от SquarecandyКак насчет использования
explode
:$input = 'Posted On April 6th By Some Dude'; $result = explode(' By',$input); return $result[0];
Преимущества:
$result[1]
вернетсяSome Dude
в этом примере)источник
Вы могли сделать:
$posted = preg_replace('/ By.*/', '', $posted); echo $posted;
источник
Один из способов:
$str = 'Posted On April 6th By Some Dude'; echo strtok($str, 'By'); // Posted On April 6th
источник
By
, а по любому символу во втором параметре. Это означает, что он будет разделен наB
илиy
. Технически, это не все доBy
.strtok('a:b', ':')
вернет,a
ноstrtok(':b', ':')
вернетb
, а не пустую строку, как вы ожидали.Попробуй это.
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",","); ?>
источник
Ответ Остина работает для вашего примера.
В более общем плане вам следует изучить функции регулярных выражений, когда подстрока, которую вы разделяете, может различаться между строками:
источник
Вы можете использовать
list
иexplode
функции:list($result) = explode("By", "Posted On April 6th By Some Dude", 2); // $result is "Posted On April 6th "
источник
$var = "Posted On April 6th By Some Dude"; $new_var = substr($var, 0, strpos($var, " By"));
источник
preg_replace
предлагает один способ:$newText = preg_replace('/\bBy.*$/', '', $text);
источник
Используя регулярное выражение:
$string = preg_replace('/\s+By.*$/', '', $string)
источник
Ниже приведен наиболее эффективный метод (во время выполнения), чтобы отрезать все после первого 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 }
Поначалу регулярные выражения могут показаться запутанными, но они могут быть действительно мощными и вашими лучшими друзьями, когда вы их освоите! Удачи!
источник
Зачем...
Это, вероятно, излишне для нужд большинства людей, но оно касается ряда вещей, которых нет в каждом отдельном ответе выше. Из пунктов, которые он адресовал, три из них были необходимы для моих нужд. С жесткими скобками и отбрасыванием комментариев это все еще могло оставаться читаемым всего на 13 строках кода.
Это касается следующего:
Применение:
Отправьте исходную строку, поиск 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 } }
источник
Используйте функцию strstr .
<?php $myString = "Posted On April 6th By Some Dude"; $result = strstr($myString, 'By', true); echo $result ;
Третий параметр
true
указывает функции вернуть все до первого появления второго параметра.источник
strtok($str, 'By')
выглядит проще$variable = substr($initial, 0, strpos($initial, "By")); if (!empty($variable)) { echo $variable; } else { echo $initial; }
источник