Co się stanie, jeśli podciąg wystąpi dwukrotnie (lub więcej)?
Bart Kiers
18
Uwaga: jeśli robisz to, aby móc zabrać czyjąś zawartość i zaprezentować ją na własnej stronie, nie rób tego .
ceejayoz
Zgadzam się z ceejayoz. To brzmi bardzo tak, jakbyś próbował użyć treści, do której tak naprawdę nie masz dostępu, i próbujesz usunąć wszelkie odniesienia do oryginalnego autora. To nie byłoby zbyt miłe ...
Podczas pracy z treścią generowaną przez CMS często trzeba robić tego typu rzeczy z uzasadnionych powodów. Powodem jest to, że nigdy nie chcesz zadzierać z rzeczywistym kodem, który tworzy taki fragment kodu, ponieważ będziesz przerywać aktualizacje; więc pozwalasz mu robić swoje, a potem robisz swoje.
Masz rację. strpos zwróci FALSE, jeśli „By” nie zostanie znalezione. substr zwróci pusty ciąg, jeśli podana długość jest fałszywa. W praktyce prawdopodobnie przydatne byłoby sprawdzenie, czy istnieje „By”, a następnie zrobienie tego tylko wtedy, gdy tak jest (w przeciwnym razie pozostawienie samego ciągu).
Umieściłem odpowiedź, która moim zdaniem odnosi się do wszystkiego poniżej, a także wyjaśnia sposoby radzenia sobie z różnymi rzeczami, takimi jak niewrażliwość na wielkość liter, wielokrotne wystąpienia i wyrażenia regularne. Jeśli ktoś chce zrobić coś bardziej elastycznego lub nie ma kontroli nad wprowadzanymi danymi wejściowymi, prawdopodobnie warto to sprawdzić.
azoundria
1
Działa idealnie dla mnie @Goahnary!
denis
106
Jeśli używasz PHP 5.3+, spójrz na flagę $ before_needle funkcji strstr ()
$s ='Posted On April 6th By Some Dude';
echo strstr($s,'By',true);
Regex jest wolniejszy niż eksplodować (zakładam, że preg_split ma podobną szybkość do innych opcji wyrażenia regularnego sugerowanych w innych odpowiedziach)
Udostępnia również drugą część ciągu, jeśli jej potrzebujesz ( $result[1]zwróci Some Dudew tym przykładzie)
+1 To jedyny, który działa, jeśli znaki kontrolne NIE są obecne (w przeciwieństwie do innych, które zwracają pusty ciąg, jeśli znaki kontrolne nie są obecne w ciągu źródłowym)
Tom Auger
9
Jedną z metod byłoby:
$str ='Posted On April 6th By Some Dude';
echo strtok($str,'By');// Posted On April 6th
Jest to najlepsza odpowiedź, która działa, nawet jeśli By nie ma w ciągu, odpowiedź substr jest błędna, ponieważ jest przez doest'nt exist i nie powiedzie się.
neoteknic
To jest niepoprawne: funkcja nie będzie dzielona według By, ale według dowolnego znaku w drugim parametrze. Oznacza to, że zostanie podzielony na jeden Blub y. Technicznie rzecz biorąc, nie uzyskuje się wszystkiego przed By.
msb
Bądź ostrożny: strtok zwraca część łańcucha po znaku, jeżeli jest to pierwszy znak w ciągu np strtok('a:b', ':')powróci aale strtok(':b', ':')wróci b, nie pusty ciąg jak można się spodziewać.
Quinn Comendant
6
Spróbuj tego.
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;}}
Stosowanie:
<?php//returns Apples
$clean_string= strip_after_string ("Apples, Oranges, Banannas",",");?>
Znacznie lepiej byłoby nazwać funkcję strip_after_string zamiast sas i mieć bazę kodu pełną tajemniczych inicjalizacji. Jest to jednak moja ulubiona i najbardziej czytelna odpowiedź na to pytanie.
Anther
5
Odpowiedź Austina działa w twoim przykładowym przypadku.
Mówiąc bardziej ogólnie, dobrze byłoby przyjrzeć się funkcjom wyrażeń regularnych, gdy podciąg, na którym dzielisz, może różnić się między łańcuchami:
+1, to prawda. Gdybyś chciał podzielić na „Autor:” lub „Autor:” lub „Użyte za zgodą:”, prawdopodobnie najłatwiej byłoby zrobić wyrażenie regularne. Kiedy jednak nie stosuję żadnej logiki wyrażeń regularnych, staram się ich unikać, ponieważ wydają się one natychmiast dodawać poziom złożoności do kodu (przynajmniej dla mnie)
Prosimy o dołączenie wyjaśnień do odpowiedzi zawierającej tylko kod.
mickmackusa,
2
Poniżej znajduje się najbardziej wydajna metoda (według czasu wykonywania) odcinania wszystkiego po pierwszym By w ciągu. Jeśli By nie istnieje, zwracany jest pełny ciąg. Wynik jest w $ 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"
Jeśli nie chcesz uwzględniać wielkości liter, użyj stripos zamiast strpos. Jeśli uważasz, że By może istnieć więcej niż raz i chcesz wyciąć wszystko po ostatnim wystąpieniu, użyj strrpos .
Poniżej znajduje się mniej wydajna metoda, ale zajmuje mniej miejsca na kod. Ta metoda jest również bardziej elastyczna i umożliwia wykonanie dowolnego wyrażenia regularnego.
$sInputString ="Posted On April 6th By Some Dude";
$pControl ="By";
$sResult = preg_replace("' ".$pControl.".*'s",'', $sInputString);//$sResult = "Posted On April 6th"
Na przykład, jeśli chcesz usunąć wszystko po dniu:
$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"
Aby nie rozróżniać wielkości liter, dodaj modyfikator i w następujący sposób:
Ale tutaj jest również naprawdę potężny sposób, w jaki możesz użyć preg_match do zrobienia tego, co prawdopodobnie próbujesz zrobić:
$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}
Wyrażenia regularne mogą początkowo wydawać się zagmatwane, ale mogą być naprawdę potężne i być najlepszym przyjacielem, gdy je opanujesz! Powodzenia!
Jest to prawdopodobnie przesada dla większości ludzi, ale dotyczy wielu rzeczy, których nie dotyczy każda z powyższych odpowiedzi. Z pozycji, których dotyczy, trzy były potrzebne do moich potrzeb. Przy ścisłym nawiasach klamrowych i porzucaniu komentarzy może to być nadal czytelne przy zaledwie 13 liniach kodu.
Dotyczy to następujących kwestii:
Wpływ na wydajność korzystania z REGEX vs strrpos / strstr / strripos / stristr.
Używanie strripos / strrpos, gdy znak / ciąg nie został znaleziony w ciągu.
Usuwanie z lewej lub prawej strony łańcucha (pierwsze lub ostatnie wystąpienie).
Rozróżnianie wielkości liter.
Chcąc mieć możliwość zwrócenia oryginalnego ciągu niezmienionego, jeśli nie znaleziono znaku / ciągu wyszukiwania.
Stosowanie:
Wyślij oryginalny ciąg, wyszukaj znak / ciąg, „R” / „L”, aby rozpocząć po prawej lub lewej stronie, prawda / fałsz, aby uwzględnić wielkość liter. Na przykład wyszukaj „tutaj” bez rozróżniania wielkości liter, w ciągu znaków zacznij od prawej strony.
echo TruncStringAfterString("Now Here Are Some Words Here Now","here","R",false);
Rezultatem byłoby „Teraz oto kilka słów”. Zmiana „R” na „L” spowoduje wyświetlenie: „Teraz”.
Oto funkcja:
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}}
Odpowiedzi:
Mówiąc prostym językiem: podaj mi część ciągu zaczynającą się od początku i kończącą się w miejscu, w którym po raz pierwszy napotkasz separator.
źródło
Jeśli używasz PHP 5.3+, spójrz na flagę $ before_needle funkcji strstr ()
źródło
FALSE
jeśli część ciągu nie zostanie znaleziona. Tak więc rozwiązaniem mogłoby być:echo strstr($s, 'By', true) ?: $s;
explode(' By', $s)[0]
IMHO SquarecandyCo powiesz na używanie
explode
:Zalety:
$result[1]
zwróciSome Dude
w tym przykładzie)źródło
Mógłbyś:
źródło
Jedną z metod byłoby:
źródło
By
, ale według dowolnego znaku w drugim parametrze. Oznacza to, że zostanie podzielony na jedenB
luby
. Technicznie rzecz biorąc, nie uzyskuje się wszystkiego przedBy
.strtok('a:b', ':')
powrócia
alestrtok(':b', ':')
wrócib
, nie pusty ciąg jak można się spodziewać.Spróbuj tego.
Stosowanie:
źródło
Odpowiedź Austina działa w twoim przykładowym przypadku.
Mówiąc bardziej ogólnie, dobrze byłoby przyjrzeć się funkcjom wyrażeń regularnych, gdy podciąg, na którym dzielisz, może różnić się między łańcuchami:
źródło
Możesz używać
list
iexplode
funkcji:źródło
źródło
preg_replace
oferuje w jedną stronę:źródło
Używając wyrażenia regularnego:
$string = preg_replace('/\s+By.*$/', '', $string)
źródło
Poniżej znajduje się najbardziej wydajna metoda (według czasu wykonywania) odcinania wszystkiego po pierwszym By w ciągu. Jeśli By nie istnieje, zwracany jest pełny ciąg. Wynik jest w $ sResult.
Jeśli nie chcesz uwzględniać wielkości liter, użyj stripos zamiast strpos. Jeśli uważasz, że By może istnieć więcej niż raz i chcesz wyciąć wszystko po ostatnim wystąpieniu, użyj strrpos .
Poniżej znajduje się mniej wydajna metoda, ale zajmuje mniej miejsca na kod. Ta metoda jest również bardziej elastyczna i umożliwia wykonanie dowolnego wyrażenia regularnego.
Na przykład, jeśli chcesz usunąć wszystko po dniu:
Aby nie rozróżniać wielkości liter, dodaj modyfikator i w następujący sposób:
Aby dostać wszystko za ostatnim By jeśli uważasz, że może być więcej niż jeden, dodać dodatkową * na początku tak.:
Ale tutaj jest również naprawdę potężny sposób, w jaki możesz użyć preg_match do zrobienia tego, co prawdopodobnie próbujesz zrobić:
Wyrażenia regularne mogą początkowo wydawać się zagmatwane, ale mogą być naprawdę potężne i być najlepszym przyjacielem, gdy je opanujesz! Powodzenia!
źródło
Czemu...
Jest to prawdopodobnie przesada dla większości ludzi, ale dotyczy wielu rzeczy, których nie dotyczy każda z powyższych odpowiedzi. Z pozycji, których dotyczy, trzy były potrzebne do moich potrzeb. Przy ścisłym nawiasach klamrowych i porzucaniu komentarzy może to być nadal czytelne przy zaledwie 13 liniach kodu.
Dotyczy to następujących kwestii:
Stosowanie:
Wyślij oryginalny ciąg, wyszukaj znak / ciąg, „R” / „L”, aby rozpocząć po prawej lub lewej stronie, prawda / fałsz, aby uwzględnić wielkość liter. Na przykład wyszukaj „tutaj” bez rozróżniania wielkości liter, w ciągu znaków zacznij od prawej strony.
Rezultatem byłoby „Teraz oto kilka słów”. Zmiana „R” na „L” spowoduje wyświetlenie: „Teraz”.
Oto funkcja:
źródło
Użyj funkcji strstr .
Trzeci parametr
true
mówi funkcji, aby zwróciła wszystko przed pierwszym wystąpieniem drugiego parametru.źródło
strtok($str, 'By')
wygląda prościejźródło