Regex-variabelen maken om routes vast te leggen

iedereen kan me helpen met dit probleem.

example $uri = '/username/carlos'; => $routes[] = '/username/@name';

@name convert in variable $ name capturing string "carlos"

$routes[] = '/list/edit/@id:[0-9]{3}';

$routes[] = '/username/@name';

$routes[] = '/archive/*';

$routes[] = '/';


$uri = '/username/carlos';

foreach ( $routes as $pattern )
{
    if ( preg_match( '#^' . preg_replace( '#(?:{{)[email protected](\w+\b)(?:}})?#i', '(?P<\1>[\w\-\.!~\*\'"(),\s]+)',
                            str_replace( '\*', '(.*)', preg_quote( $pattern, '/' ) ) ) . '\/?$#i', $uri, $matchs ) )
    {

        //how to make regex for this to work :


        echo $name;//carlos =>$uri = '/username/carlos'; or matt => $uri = '/username/matt';

    }
}

bedankt voor het lezen

1
Waarom gebruik je geen kant en klaar routeringskader? En zou u niet eerst het geneste patroonconversiegedeelte moeten breken om het te debuggen?
toegevoegd de auteur mario, de bron

1 antwoord

Er is veel meer werk dat u moet doen om dit te laten werken, vooral om de route om te zetten in reguliere expressies die u vervolgens kunt gebruiken voor de gegeven URI. De manier waarop ik het zou doen is als volgt

$routes = $params = array();

$routes[] = '/list/edit/@id:[0-9]{3}';
$routes[] = '/username/@name';
$routes[] = '/archive/*';
$routes[] = '/';

$uri = '/username/carlos';

foreach($routes as $pattern) {
   //Convert all characters into safe characters
    $pattern = preg_quote($pattern, '~');

   //Convert * into .*?
    $pattern = preg_replace('/(?'.print_r($pattern, true).'
'; //Convert any @name:expression into their expressions for capture $pattern = preg_replace_callback('%@([a-zA-Z]+)(\\\\:([^/]+))?%', 'regex_callback', $pattern); $pattern = '~^' . $pattern . '$~'; if(preg_match($pattern, $uri, $matches)) { $params = $matches; break; } } echo '
'.print_r($params, true).'
'; function regex_callback($data) { #echo '
'.print_r($data, true).'
'; $pattern = '[^/]+'; if(!empty($data[3])) { $pattern = stripslashes($data[3]); } return '(?P<' . $data[1] . '>' . $pattern . ')'; }

It converts the * into .*?, and then converts the @param into (?P[^/]+), or substituting [^/]+ for the expression after the :

Als er een overeenkomst wordt gevonden, worden de overeenkomsten ingesteld op $ params en wordt de foreach-lus afgesloten. Om de naam te vinden, zou je die dan gewoon moeten gebruiken

echo $param['name'];
1
toegevoegd
U zou in plaats daarvan basename kunnen gebruiken om dat op te halen. php.net/basename
toegevoegd de auteur Jay Gilford, de bron
Hallo, hoe regex voor $ uri = '/list/edit/123.html'; met $ routes [] = '/list/edit/@id:[0-9]{3}.html'; resultaat is "123.html" maar geen werk enkele var "123" sorry mijn Engels!
toegevoegd de auteur zetanova, de bron