2010-11-24 7 views
0

Quelqu'un pourrait-il me dire comment je ferais cela. J'ai 3 cordes.Comparer les chaînes et extraire les variables?

$route = '/user/$1/profile/$2'; 
$path = '/user/profile/$1/$2'; 
$url = '/user/jason/profile/friends'; 

Ce que je dois faire est de vérifier si l'URL est conforme à la route. J'essaie de faire ceci comme suit. Je suppose que la regex fonctionne, c'est la première fois que j'ai écrit par moi-même. : D

C'est ici que je suis coincé. Comment puis-je comparer les chaînes suivantes:

$route = '/user/$1/profile/$2'; 
$url = '/user/jason/profile/friends'; 

Alors je finis avec:

array (
    '$1' => 'jason', 
    '$2' => 'friends' 
); 

Je suppose que ce tableau je pourrais alors str_replace ces valeurs dans la variable $ path?

Répondre

1
$route_segments = explode('/',$route); 
$url_segments = explode('/',$url); 
$combined_segments = array_combine($route_segments,$url_segments); 

et Untested ne sais pas comment il réagit avec des longueurs de tableau inégales, mais qui est probablement ce que vous cherchez au sujet d'un élément à élément correspondance. Ensuite, vous pouvez à peu près itérer le tableau et chercher $ et utiliser l'autre valeur pour le remplacer.

EDIT

/^\x24[0-9]+$/ 

Fermer sur le RegEx sauf que vous devez "Escape" le $ dans un regex parce que c'est un drapeau pour la fin de chaîne (ainsi le \ x24). Le [0-9] + correspond à 1+ nombre (s). Les moyens^correspondent au début de la chaîne et, comme expliqué, les moyens $ correspondent à la fin. Cela assurera que c'est toujours un signe dollar puis un nombre.

(en fait, netcoder a une belle solution)

+0

J'aime cette solution, c'est simple et précis. Merci pour le conseil sur l'expression rationnelle. – JasonS

1

j'ai fait quelque chose de similaire dans un petit cadre de mon propre.

Ma solution était de transformer l'URL du modèle: /user/$1/profile/$2

dans une expression rationnelle capable de paramètres d'analyse syntaxique: ^\/user\/([^/]*)/profile/([^/]*)\/$

Je puis vérifier si les matchs de regexp ou non. Vous pouvez jeter un oeil à my controller code si vous avez besoin.

+0

Le principal argument de vente de ma petite application est la simplicité. Je pense que cela irait à l'encontre de ce principe. C'est une bonne solution mais merci. – JasonS

+0

Je pense que vous avez mal compris mon argument. Je ne suggérais pas que vous demandiez à votre utilisateur d'entrer regexp au lieu de votre langage plus naturel. Je vous suggérais de transformer votre modèle d'URL en langage naturel en regexp à l'exécution afin de faire correspondre plus facilement l'URL actuelle. –

1

Vous pouvez le faire:

$route = '/user/$1/profile/$2'; 
$path = '/user/profile/$1/$2'; 
$url = '/user/jason/profile/friends'; 

$regex_route = '#'.preg_replace('/\$[0-9]+/', '([^/]*)', $route).'#'; 
if (preg_match($regex_route, $url, $matches)) { 
    $real_path = $path; 
    for ($i=1; $i<count($matches); $i++) { 
     $real_path = str_replace('$'.$i, $matches[$i], $real_path); 
    } 
    echo $real_path; // outputs /user/profile/jason/friends 
} else { 
    // route does not match 
} 
0

Vous pouvez remplacer toutes les occurrences de $n par un named group avec le même nombre (?P<_n>[^/]+) puis l'utiliser comme modèle pour preg_match:

$route = '/user/$1/profile/$2'; 
$path = '/user/profile/$1/$2'; 
$url = '/user/jason/profile/friends'; 

$pattern = '~^' . preg_replace('/\\\\\$([1-9]\d*)/', '(?P<_$1>[^/]+)', preg_quote($route, '~')) . '$~'; 
if (preg_match($pattern, $url, $match)) { 
    var_dump($match); 
} 

Cette impression en ce cas:

array(5) { 
    [0]=> 
    string(28) "/user/jason/profile/friends" 
    ["_1"]=> 
    string(5) "jason" 
    [1]=> 
    string(5) "jason" 
    ["_2"]=> 
    string(7) "friends" 
    [2]=> 
    string(7) "friends" 
} 

L'utilisation d'une expression régulière vous permet d'utiliser les caractères génériques à n'importe quelle position dans le chemin et pas seulement en tant que segment de chemin séparé (par ex./~$1/ pour /~jason/ fonctionnerait aussi). Et sous-modèles nommés vous permet d'utiliser un ordre arbitraire (par exemple /$2/$1/ fonctionne aussi bien).

Et pour un échec rapide, vous pouvez également utiliser le atomic grouping syntax (?>…).

Questions connexes