2010-09-30 8 views
1

C'est quelque chose que je pourrais bidouiller ensemble, mais je me demandais si quelqu'un avait une solution propre à mon problème. Quelque chose que je jette ensemble ne sera pas nécessairement très concis ou rapide!Couper seulement la première et dernière occurrence d'un caractère dans une chaîne (PHP)

J'ai une chaîne comme ceci ///hello/world///. Je n'ai besoin de dépouiller que le premier et le dernier slash, aucun des autres, de sorte que j'obtiens une chaîne comme celle-ci //hello/world//.

Le trim de PHP n'est pas tout à fait exact: effectuer trim($string, '/') retournera hello/world. Une chose à noter est que la chaîne n'aura pas nécessairement de barres obliques au début ou à la fin. Voici quelques exemples de ce que je voudrais arriver à différentes chaînes:

///hello/world/// > //hello/world// 
/hello/world/// > hello/world// 
hello/world/ > hello/world 

Merci d'avance pour toute aide!

+0

Pourquoi ne pas apporter un exemple du monde réel au lieu de un tel mannequin? Peut-être qu'il peut y avoir une meilleure solution, pour votre cas seulement? Un cas réel. –

+0

@col Ceci est presque monde réel. Cela fait partie d'une classe de routage qui reçoit le chemin d'URL actuel pour le router vers le contrôleur approprié. Je viens de remarquer que 'http: // example.com/path/to/file' se résout au même contrôleur que' http: //example.com /// chemin/en/fichier // ', donc l'exemple ci-dessus est presque exactement ce que les chaînes que je vais ressembler :) Je gère les chemins – Rowan

+0

Mais quelle est la raison d'avoir de telles barres multiples? Les chemins ont besoin d'un seul. Je n'ai jamais vu de chemin comme celui-ci: '/// chemin/vers/fichier //'. Où les obtenez-vous et pourquoi ne voulez-vous pas normaliser, ce qui en fait habituel/chemin/vers/fichier /? –

Répondre

8

La première chose sur mon esprit:

if ($string[0] == '/') $string = substr($string,1); 
if ($string[strlen($string)-1] == '/') $string = substr($string,0,strlen($string)-1); 
+1

Je crois que la méthode de sous-chaîne serait probablement beaucoup plus rapide que l'expression régulière. – Kevin

+0

Ceci est très grossièrement ce que je me lancerais ensemble .. Je voudrais éviter regex si ça va être plus lent, y at-il des statistiques pour sauvegarder la vitesse des fonctions de manipulation de chaînes simples vs regex? – Rowan

+3

@Rowan: non, il n'y a pas de telles statistiques, car elles dépendent de la manipulation réelle, parfois les expressions rationnelles gagnent.La seule façon de le dire est de le comparer à vos attentes, et même alors, je dirais que l'utilisation de l'un sur l'autre en fonction de la performance est probablement une micro-optimalisation. – Wrikken

0

Je pense que c'est ce que vous vous cherchez:

preg_replace('/\/(\/*[^\/]*?\/*)\//', '\1', $text); 
+2

Argh, ne pouvez-vous pas simplement changer de délimiteur? '#/(/ * [^ /] *?/*)/#'. Cependant, vous oubliez de l'ancrer: '# ^/(/ * [^ /] *?/*) $/#', Et pour des raisons d'efficacité, vous pouvez également utiliser 'preg_replace ('# (^/|/$) # ',' ', $ text); ' – Wrikken

+3

La différence entre'/\/(\/* [^ \ /] *? \/*) \ // 'et' # (^/|/$) # ' C'est pourquoi les gens sont rapides à écrire regex comme illisible. –

0

Une autre regex, en utilisant des références arrières:

preg_replace('/^(\/?)(.*)\1$/','\2',$text); 

Cette a l'avantage que, si vous voulez utiliser des caractères autres que /, vous pouvez le faire plus lisiblement. Il force également le caractère/à commencer et terminer la chaîne, et permet/d'apparaître dans la chaîne. Enfin, il ne supprime le personnage que du début s'il y a un personnage à la fin, et vice versa.

0

Encore une autre mise en œuvre:

function otrim($str, $charlist) 
{ 
return preg_replace(sprintf('~^%s|%s$~', preg_quote($charlist, '~')), '', $str); 
} 
+0

Cela m'a donné 'Erreur fatale: Uncaught ErrorException: sprintf(): Trop peu d'arguments' –

0

Il a été plus de 6 ans il y a, mais je donne peut répondre de toute façon:

function trimOnce($value) 
{ 
    $offset = 0; 
    $length = null; 
    if(mb_substr($value,0,1) === '/') { 
     $offset = 1; 
    } 
    if(mb_substr($value,-1) === '/') { 
     $length = -1; 
    } 
    return mb_substr($value,$offset,$length); 
} 
Questions connexes