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


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.


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);

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:


@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;

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

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:

$ variable = preg_replace ('/ By. * /', '', $ variable);

+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 "

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"));


2

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


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!


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
    }           

}

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.


1
strtok($str, 'By')semble plus simple
mu3

-2
$variable = substr($initial, 0, strpos($initial, "By"));

if (!empty($variable)) { echo $variable; } else { echo $initial; }
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.