Supprimer une partie d'une chaîne après un certain caractère

144

Je me demande simplement comment je pourrais tout supprimer après une certaine sous-chaîne en PHP

ex:

Posted On April 6th By Some Dude

Je voudrais l'avoir pour qu'il supprime tout le texte, y compris, et après, la sous-chaîne "Par"

Merci

Poisson Belgin
la source
1
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 ...
selfawaresoup
2
Excellente solution alternative stackoverflow.com/a/9315908/1518921 :)
Guilherme Nascimento
1
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.
Nosajimiki

Réponses:

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

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.

Austin Fitzpatrick
la source
11
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).
Austin Fitzpatrick
13
Cela fonctionne: strpos ($ variable, "By")? substr ($ variable, 0, strpos ($ variable, "Par")): $ variable;
Noah Gary
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);
VolkerK
la source
4
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:

bonbon
la source
@bkac - Quel est le problème avec le démodé tant qu'il fonctionne et n'est pas amorti?
squarecandy
3
Cela élimine la vérification supplémentaire de l'existence de la chaîne de délimitation requise par la réponse acceptée.
David Cullen
17

Vous pourriez faire:

$posted = preg_replace('/ By.*/', '', $posted);
echo $posted;
JYelton
la source
4
+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
HADI
la source
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",",");
?>
Tim Yobson
la source
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:

$ variable = preg_replace ('/ By. * /', '', $ variable);
jemfinch
la source
+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)
Austin Fitzpatrick
4

Vous pouvez utiliser listet explodefonctions:

list($result) = explode("By", "Posted On April 6th By Some Dude", 2);
// $result is "Posted On April 6th "
Salman A
la source
C'est le plus précis. Comment j'aimerais pouvoir voter pour cela deux fois
John Max
4
$var = "Posted On April 6th By Some Dude";
$new_var = substr($var, 0, strpos($var, " By"));
Tim Cooper
la source
2

preg_replace offre un moyen:

$newText = preg_replace('/\bBy.*$/', '', $text);
outis
la source
2

En utilisant une expression régulière: $string = preg_replace('/\s+By.*$/', '', $string)

Ming-Tang
la source
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:

$sResult = preg_replace("' ".$pControl.".*'si", '', $sInputString);

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:

$sResult = preg_replace("'.* ".$pControl.".*'si", '', $sInputString);

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!

azoundrie
la source
1

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:

  • 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:

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
    }           

}
Robert Mauro
la source
Si vous rejetez ma réponse de travail, nous vous serions reconnaissants d’indiquer pourquoi.
Robert Mauro
0

Utilisez la fonction strstr .

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

echo $result ;

Le troisième paramètre trueindique à la fonction de tout renvoyer avant la première occurrence du deuxième paramètre.

Faisal
la source
1
strtok($str, 'By')semble plus simple
mu3
-2
$variable = substr($initial, 0, strpos($initial, "By"));

if (!empty($variable)) { echo $variable; } else { echo $initial; }
valente
la source