82 votes

Supprime une partie d'une chaîne de caractères, mais seulement si elle se trouve à la fin de la chaîne.

J'ai besoin de supprimer une sous-chaîne d'une chaîne, mais uniquement lorsqu'elle se trouve à la FIN de la chaîne.

par exemple, en supprimant 'string' à la fin des chaînes suivantes :

"this is a test string" ->  "this is a test "
"this string is a test string" - > "this string is a test "
"this string is a test" -> "this string is a test"

Une idée ? Probablement une sorte de preg_replace, mais comment ?

0 votes

Vous pourriez trouver s($str)->replaceSuffix('string') utile, comme on le trouve dans cette bibliothèque autonome .

128voto

Tim Cooper Points 55292

Vous noterez l'utilisation de la fonction $ qui indique la fin d'une chaîne de caractères :

$new_str = preg_replace('/string$/', '', $str);

Si la chaîne est une variable fournie par l'utilisateur, il est bon de la faire passer par preg_quote d'abord :

$remove = $_GET['remove']; // or whatever the case may be
$new_str = preg_replace('/'. preg_quote($remove, '/') . '$/', '', $str);

0 votes

Est-ce que preg_quote/preg_replace fonctionne également avec des chaînes de caractères non ASCII (disons UTF-8) ? preg_* les familles de fonctions conscientes de l'encodage ? Qu'en est-il [^[:alnum:]] classe de caractères ?

1 votes

Cela n'enlève pas l'espace avant "string" s'il existe. Vous pourriez également utiliser substring sur les 6 derniers caractères, les comparer à "string", et s'il y a une correspondance, les soustraire. Ce serait beaucoup plus rapide que Regex.

1 votes

Cela ne devrait pas être la réponse acceptée. Utiliser preg_replace pour cette tâche est laid comme l'enfer, faux en logique, et un gaspillage total d'énergie/temps/cycles de serveur (oui, cela compte, vous payez votre hébergement plus cher parce que 10000000 des pages web des autres utilisateurs utilisent preg_replace au lieu de substr).

30voto

Skrol29 Points 2711

L'utilisation de regexp peut échouer si la sous-chaîne contient des caractères spéciaux.

Ce qui suit fonctionnera avec toutes les chaînes de caractères :

$substring = 'string';
$str = "this string is a test string";
if (substr($str,-strlen($substring))===$substring) $str = substr($str, 0, strlen($str)-strlen($substring));

14 votes

La dernière partie peut être simplement $str = substr($str, 0, -strlen($substring)); Upvoted comme bonne alternative pour regex. J'ai trouvé la même réponse à mon problème. J'utiliserais des fonctions de chaîne pures plutôt que preg_* familles à tout moment si cela sert mon but

2 votes

Une solution simple et intelligente pour un problème supposé simple sans utiliser d'expressions régulières. merci.

1 votes

Comme le disent certains, "si votre solution nécessite l'utilisation de regex, vous avez maintenant deux problèmes". Donc, pour le plaisir, j'ai voulu résoudre ce problème pour les non-regex et j'étais venu avec exactement ceci et le commentaire de @Sudhi avant de voir votre réponse. Le petit détail dont je n'étais pas conscient est que vous pouvez placer "-" pour annuler plutôt que de multiplier par -1. Merci donc.

10voto

Bas Points 905

J'ai écrit ces deux fonctions pour la coupe à gauche et à droite d'une chaîne :

/**
 * @param string    $str           Original string
 * @param string    $needle        String to trim from the end of $str
 * @param bool|true $caseSensitive Perform case sensitive matching, defaults to true
 * @return string Trimmed string
 */
function rightTrim($str, $needle, $caseSensitive = true)
{
    $strPosFunction = $caseSensitive ? "strpos" : "stripos";
    if ($strPosFunction($str, $needle, strlen($str) - strlen($needle)) !== false) {
        $str = substr($str, 0, -strlen($needle));
    }
    return $str;
}

/**
 * @param string    $str           Original string
 * @param string    $needle        String to trim from the beginning of $str
 * @param bool|true $caseSensitive Perform case sensitive matching, defaults to true
 * @return string Trimmed string
 */
function leftTrim($str, $needle, $caseSensitive = true)
{
    $strPosFunction = $caseSensitive ? "strpos" : "stripos";
    if ($strPosFunction($str, $needle) === 0) {
        $str = substr($str, strlen($needle));
    }
    return $str;
}

7voto

Pascal MARTIN Points 195780

Je suppose que vous pourriez utiliser un expression régulière qui correspondrait à string et, ensuite, fin de la chaîne couplé à la preg_replace() fonction.

Quelque chose comme ceci devrait fonctionner parfaitement :

$str = "this is a test string";
$new_str = preg_replace('/string$/', '', $str);

Notes :

  • string correspond... eh bien... string
  • et $ signifie fin de la chaîne

Pour plus d'informations, vous pouvez lire le Syntaxe des motifs du manuel PHP.

2voto

Preg_replace et ce modèle : /chaîne \z /i

\z signifie la fin de la chaîne

http://tr.php.net/preg_replace

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X