Regex to capture infinite groups in a URL separating them by the slash

4

I would like to know how I could do a regex to capture multiple groups as demonstrated in the string below:

/ Controller / Action / Param1 / Param2 / Param3 / ...

I want to catch "Controller", "Action", "Param1", "Param2", "Param3", and the more that are separated by the slash, each must be a different match so that you can use% them in a vector.

    
asked by anonymous 24.02.2017 / 02:16

4 answers

2

Using Regular Expression

Although the easiest way to resolve it is explode , if you want to use regular expression , here it is:

$input = '/Controller/Action/Param1/Param2/Param3/';

preg_match_all("/\/?([^\/]+)/", $input, $output);

var_dump($output[1]);
    
24.02.2017 / 12:31
6

Does it really need to be a regular expression? How about using a explode() ?

<?php
$str = 'Controller/Action/Param1/Param2/Param3';

$segments = explode('/', $str));
print_r($segments);

This example will return:

Array ( 
    [0] => Controller 
    [1] => Action 
    [2] => Param1 
    [3] => Param2 
    [4] => Param3 
)

See running .

If you still want to use a regex, something that can bring you the same result is preg_split() (only slower compared to explode )

$str = 'Controller/Action/Param1/Param2/Param3';

$segments = preg_split('/\//', $str);

print_r($segments);

Result:

Array ( 
    [0] => Controller 
    [1] => Action 
    [2] => Param1 
    [3] => Param2 
    [4] => Param3 
)

Example running .

    
24.02.2017 / 02:51
5

It does not really make sense to use regex for this, but it's possible:

With regex     

$url = 'http://example.com/Controller/Action/Param1/Param2/Param3/...';

preg_match_all( '|/([^\/]+)|', $url, $matches );

var_dump( $matches );

array(2) {
  [0]=>
  array(7) {
    [0]=>
    string(12) "/example.com"
    [1]=>
    string(11) "/Controller"
    [2]=>
    string(7) "/Action"
    [3]=>
    string(7) "/Param1"
    [4]=>
    string(7) "/Param2"
    [5]=>
    string(7) "/Param3"
    [6]=>
    string(4) "/..."
  }
  [1]=>
  array(7) {
    [0]=>
    string(11) "example.com"
    [1]=>
    string(10) "Controller"
    [2]=>
    string(6) "Action"
    [3]=>
    string(6) "Param1"
    [4]=>
    string(6) "Param2"
    [5]=>
    string(6) "Param3"
    [6]=>
    string(3) "..."
  }
}

No regex

$url = 'http://example.com/Controller/Action/Param1/Param2/Param3/...';
$split = explode( '/', $url );

var_dump( $split );

array(9) {
  [0]=>
  string(5) "http:"
  [1]=>
  string(0) ""
  [2]=>
  string(11) "example.com"
  [3]=>
  string(10) "Controller"
  [4]=>
  string(6) "Action"
  [5]=>
  string(6) "Param1"
  [6]=>
  string(6) "Param2"
  [7]=>
  string(6) "Param3"
  [8]=>
  string(3) "..."
}

See working

    
24.02.2017 / 02:56
0

I find it easier and smarter to make such parameters follow a logic. Make the script smart and do not try to process anything that is not part of the system. ignore or make a face exception. A responsive execution.
All your controllers start with (Controller_) everything you live after (Controller_) is what we want to get to know which controller and which classes we'll call to that URL. Actions begin with (Actions_) what comes after (Action_) is what we get to know what action to call in our class and which class to raise. Finally it would come the parameters that would be all the parameters:

Action (a-zA-Z] +)) (?: /) + (?: [/])?

<?php

preg_match('/^(?:[\/](?:Controller_([a-zA-Z]+)))(?:[\/]Action_([a-zA-Z]+))(?:[\/]([a-zA-Z0-9\/\-\_]+))+(?:[\/])?/', $onde, $matches);

//Analisamos o controller se tiver um controller fazemos algo se
//não houver deixa tudo para lá sem controller não há trabalho a se fazer
if((isset($matches[1]) == true) and ($matches[1] != null) ){

//Já que tem controller na variável $matches[1] seguimos em frente

// Verificamos se há action, pois se não houver paramos
// por aqui e retorna a ação padrão do referido controller
if((isset($matches[2]) == true) and ($matches[2] != null) ){

// Se estamos aqui é por que tem um action a ser executado
// Então proseguimos

//Agora verificamos se tem parâmetros, se não houver essa parte não é executada
// e é executada somente a ação padrão para o referido action

if((isset($matches[3]) == true) and ($matches[3] != null) ){

// Como estamos aqui quer dizer que há parâmetros na variável $matches[3]
// Aplicamos um explode() nele

$pedacos = explode("/", $matches[3]);

//Analisamos cada parâmetros e tomamos decisões

}

}

}
?>

This regular expression accepts:

/ Controller_carrier / Action_pagar / Param1 / Param2 / Param3 /
/ Controller_carrier / Action_pagar / Param1 / Param2 / Param3
/ Controller_carrinho / Action_pagar / Param1 /
/ Controller_carrier / Action_pagar / Param1
/ Controller_carrier / Action_pagar
/ Controller_carrinho / Action_pagar /
/ Controller_carrinho /
/ Controller_carrinho


The controller can be anything as long as it follows the logic

Controller_comprar
Controller_vender
Controller_fazerpao
Controller_listarproducts
Controller_fazercafe
Controller_comerarroz
The variables are: > $ matches [1]
The name of the controler, only what comes after the underline

$ matches [2]
The name of the action, only what comes after the underline

$ matches [3]
All parameters as long as they are letters with or without numbers and dashes and underline.
It does not matter if there is a dash at the end, since it is ignored and anything that does not fit into it is also ignored.

Note: In the case of missing a part there are no errors, the variable will have a null value.
I use this logic so I do not have to use $ _GET on my site and not analyze anything that is not part of it. does not follow the logic of the system.

Hope it helps someone!

    
25.02.2017 / 16:31