Que faire si la sous-chaîne apparaît deux fois (ou plus)?
Bart Kiers
18
Juste une note, si vous faites cela pour pouvoir prendre le contenu de quelqu'un d'autre et le présenter sur votre propre site, ne le faites pas .
ceejayoz
Je suis d'accord avec ceejayoz. Cela ressemble beaucoup à ce que vous essayez d'utiliser du contenu auquel vous n'avez pas vraiment accès et que vous essayez de supprimer toute référence à l'auteur d'origine. Ce ne serait pas très agréable ...
Il est en fait courant de devoir faire ce genre de chose pour des raisons légitimes lorsque l'on travaille avec du contenu généré par un CMS. La raison en est que vous ne voulez jamais jouer avec le code réel qui crée un extrait de code comme celui-ci parce que vous allez casser vos mises à jour; alors, vous le laissez faire son truc, puis vous faites votre truc.
En clair: donnez-moi la partie de la chaîne commençant au début et se terminant à la position où vous rencontrez pour la première fois le déliminateur.
Qu'en est-il de "ne faire cela que si" par "existe?
Alisso
3
Vous avez raison. strpos renverra FALSE si "By" n'est pas trouvé. substr renverra une chaîne vide si la longueur donnée est fausse. En pratique, il serait probablement utile de vérifier si "By" existe et de ne le faire que si c'est le cas (sinon, il suffit de laisser la chaîne seule).
Je mets une réponse qui, je pense, traite de tout ci-dessous et explique également les moyens de gérer toutes sortes de choses comme l'insensibilité à la casse, les occurrences multiples et les expressions régulières. Si quelqu'un veut faire quelque chose de plus flexible ou n'a pas de contrôle sur l'entrée entrant, cela vaut probablement la peine de vérifier.
azoundria
1
Fonctionne parfaitement pour moi @Goahnary!
denis
106
Si vous utilisez PHP 5.3+, jetez un œil à l'indicateur $ before_needle de strstr ()
$s ='Posted On April 6th By Some Dude';
echo strstr($s,'By',true);
Merci, c'est la vraie bonne réponse de nos jours !
Matmarbon
59
Notez qu'il retournera FALSEsi une partie de la chaîne n'est pas trouvée. La solution pourrait donc être:echo strstr($s, 'By', true) ?: $s;
kenorb
6
^^^ La réponse de kenorb devrait être la réponse acceptée aujourd'hui. une autre alternative serait explode(' By', $s)[0]IMHO de squarecandy
Zack Morris
En effet, la vérification d'existence de kenorb est le moyen de le faire, même s'il n'est pas nécessaire de tester la chaîne.
BarryMode
Juste ici pour dire que la méthode de @ kenorb est les seins.
Quinn Comendant
32
Que diriez-vous d'utiliser explode:
$input ='Posted On April 6th By Some Dude';
$result = explode(' By',$input);return $result[0];
Avantages:
Très lisible / compréhensible
Renvoie la chaîne complète si la chaîne de séparation ("Par" dans cet exemple) n'est pas présente. (Ne retournera pas FALSE comme certaines des autres réponses.)
+1 C'est le seul qui fonctionne si les caractères de contrôle ne sont PAS présents (contrairement aux autres qui renvoient une chaîne vide si les caractères de contrôle ne sont pas présents dans la chaîne source)
Tom Auger
9
Une méthode serait:
$str ='Posted On April 6th By Some Dude';
echo strtok($str,'By');// Posted On April 6th
C'est la meilleure réponse, cela fonctionne même si By n'est pas dans la chaîne, la réponse de la sous-chaîne est erronée car elle échoue.
neoteknic
Ceci est incorrect: la fonction ne sera pas divisée par By, mais par n'importe quel caractère du 2ème paramètre. Cela signifie qu'il sera divisé par Bou par y. Techniquement, il n'y a pas tout avant un By.
msb
Attention: strtok retournera la partie de la chaîne après le caractère si c'est le premier caractère de la chaîne, par exemple, strtok('a:b', ':')retournera amais strtok(':b', ':')retournera b, pas une chaîne vide comme on s'y attend.
Quinn Comendant
6
Essaye ça.
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;}}
Usage:
<?php
//returns Apples
$clean_string= strip_after_string ("Apples, Oranges, Banannas",",");?>
Vous feriez bien mieux de nommer la fonction strip_after_string au lieu de sas et d'avoir une base de code pleine d'initialismes cryptiques. C'est ma réponse préférée la plus lisible à cette question.
Anther
5
La réponse d'Austin fonctionne pour votre exemple.
Plus généralement, vous feriez bien d'examiner les fonctions des expressions régulières lorsque la sous-chaîne sur laquelle vous divisez peut différer entre les chaînes:
+1, c'est vrai. Si vous vouliez également diviser sur «Auteur:» ou «Écrit par:» ou «Utilisé avec le consentement de:», il serait probablement plus facile de créer une expression régulière. Quand je ne fais pas de logique regex, cependant, j'ai tendance à les éviter car ils semblent ajouter immédiatement un niveau de complexité au code (du moins pour moi)
Veuillez inclure quelques explications avec cette réponse codée uniquement.
mickmackusa
2
Vous trouverez ci-dessous la méthode la plus efficace (au moment de l'exécution) pour tout couper après le premier By d'une chaîne. Si By n'existe pas, la chaîne complète est renvoyée. Le résultat est dans $ 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"
Si vous ne voulez pas être sensible à la casse, utilisez des stripos au lieu de strpos. Si vous pensez que By peut exister plus d'une fois et que vous voulez tout couper après la dernière occurrence, utilisez strrpos .
Vous trouverez ci-dessous une méthode moins efficace mais qui prend moins d'espace de code. Cette méthode est également plus flexible et vous permet de faire n'importe quelle expression régulière.
$sInputString ="Posted On April 6th By Some Dude";
$pControl ="By";
$sResult = preg_replace("' ".$pControl.".*'s",'', $sInputString);//$sResult = "Posted On April 6th"
Par exemple, si vous souhaitez tout supprimer après la journée:
$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"
Si vous ne respectez pas la casse, ajoutez le modificateur i comme ceci:
Mais voici également un moyen très puissant d'utiliser preg_match pour faire ce que vous essayez de faire:
$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}
Les expressions régulières peuvent sembler déroutantes au début, mais elles peuvent être vraiment puissantes et devenir votre meilleur ami une fois que vous les maîtrisez! Bonne chance!
C'est probablement exagéré pour les besoins de la plupart des gens, mais cela répond à un certain nombre de choses que chaque réponse individuelle ci-dessus ne fait pas. Parmi les articles qu'il traite, trois d'entre eux étaient nécessaires pour mes besoins. Avec des crochets serrés et la suppression des commentaires, cela pourrait rester lisible à seulement 13 lignes de code.
Cela répond aux questions suivantes:
Impact sur les performances de l'utilisation de REGEX par rapport à strrpos / strstr / strripos / stristr.
Utilisation de strripos / strrpos lorsque le caractère / chaîne est introuvable dans la chaîne.
Suppression du côté gauche ou droit de la chaîne (première ou dernière occurrence).
Sensibilité au CaSe.
Vouloir la possibilité de renvoyer la chaîne d'origine inchangée si le caractère / chaîne de recherche est introuvable.
Usage:
Envoyer la chaîne d'origine, rechercher char / string, "R" / "L" pour commencer à droite ou à gauche, true / false pour la sensibilité à la casse. Par exemple, recherchez «ici» insensible à la casse, dans la chaîne, commencez par le côté droit.
echo TruncStringAfterString("Now Here Are Some Words Here Now","here","R",false);
La sortie serait "Maintenant, voici quelques mots". Changer le "R" en "L" produirait: "Now".
Voici la fonction:
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}}
Réponses:
En clair: donnez-moi la partie de la chaîne commençant au début et se terminant à la position où vous rencontrez pour la première fois le déliminateur.
la source
Si vous utilisez PHP 5.3+, jetez un œil à l'indicateur $ before_needle de strstr ()
la source
FALSE
si une partie de la chaîne n'est pas trouvée. La solution pourrait donc être:echo strstr($s, 'By', true) ?: $s;
explode(' By', $s)[0]
IMHO de squarecandyQue diriez-vous d'utiliser
explode
:Avantages:
$result[1]
reviendraitSome Dude
dans cet exemple)la source
Vous pourriez faire:
la source
Une méthode serait:
la source
By
, mais par n'importe quel caractère du 2ème paramètre. Cela signifie qu'il sera divisé parB
ou pary
. Techniquement, il n'y a pas tout avant unBy
.strtok('a:b', ':')
retourneraa
maisstrtok(':b', ':')
retournerab
, pas une chaîne vide comme on s'y attend.Essaye ça.
Usage:
la source
La réponse d'Austin fonctionne pour votre exemple.
Plus généralement, vous feriez bien d'examiner les fonctions des expressions régulières lorsque la sous-chaîne sur laquelle vous divisez peut différer entre les chaînes:
la source
Vous pouvez utiliser
list
etexplode
fonctions:la source
la source
preg_replace
offre un moyen:la source
En utilisant une expression régulière:
$string = preg_replace('/\s+By.*$/', '', $string)
la source
Vous trouverez ci-dessous la méthode la plus efficace (au moment de l'exécution) pour tout couper après le premier By d'une chaîne. Si By n'existe pas, la chaîne complète est renvoyée. Le résultat est dans $ sResult.
Si vous ne voulez pas être sensible à la casse, utilisez des stripos au lieu de strpos. Si vous pensez que By peut exister plus d'une fois et que vous voulez tout couper après la dernière occurrence, utilisez strrpos .
Vous trouverez ci-dessous une méthode moins efficace mais qui prend moins d'espace de code. Cette méthode est également plus flexible et vous permet de faire n'importe quelle expression régulière.
Par exemple, si vous souhaitez tout supprimer après la journée:
Si vous ne respectez pas la casse, ajoutez le modificateur i comme ceci:
Pour tout faire passer le dernier By si vous pensez qu'il pourrait y en avoir plus d'un, ajoutez un extra. * Au début comme ceci:
Mais voici également un moyen très puissant d'utiliser preg_match pour faire ce que vous essayez de faire:
Les expressions régulières peuvent sembler déroutantes au début, mais elles peuvent être vraiment puissantes et devenir votre meilleur ami une fois que vous les maîtrisez! Bonne chance!
la source
Pourquoi...
C'est probablement exagéré pour les besoins de la plupart des gens, mais cela répond à un certain nombre de choses que chaque réponse individuelle ci-dessus ne fait pas. Parmi les articles qu'il traite, trois d'entre eux étaient nécessaires pour mes besoins. Avec des crochets serrés et la suppression des commentaires, cela pourrait rester lisible à seulement 13 lignes de code.
Cela répond aux questions suivantes:
Usage:
Envoyer la chaîne d'origine, rechercher char / string, "R" / "L" pour commencer à droite ou à gauche, true / false pour la sensibilité à la casse. Par exemple, recherchez «ici» insensible à la casse, dans la chaîne, commencez par le côté droit.
La sortie serait "Maintenant, voici quelques mots". Changer le "R" en "L" produirait: "Now".
Voici la fonction:
la source
Utilisez la fonction strstr .
Le troisième paramètre
true
indique à la fonction de tout renvoyer avant la première occurrence du deuxième paramètre.la source
strtok($str, 'By')
semble plus simplela source