2

I'm writing routing class and need help. I need to parse $controller variable and assign parts of that string to another variables. Here is examples of $controller:

$controller = "admin/package/AdminClass::display"
//$path = "admin/package";
//$class = "AdminClass";
//$method = "display";

$controller = "AdminClass::display";
//$path = "";
//$class = "AdminClass";
//$method = "display";

$controller = "display"
//$path = "";
//$class = "";
//$method = "display";

This three situations is all i need. Yes, i can write long procedure to handle this situations, but what i need is simple solution with regex, with function preg_match_all

Any suggestion how to do this?

3
  • Please be more spcific in your question regarding other parsing situations / other strings you may need to parse. First to second value could be done via replace/substring/split. Commented Dec 22, 2011 at 20:30
  • 1
    Why do you need to use a regex? Commented Dec 22, 2011 at 20:37
  • @CanSpice, to match this three situations, and then extract parts of string to variables Commented Dec 22, 2011 at 20:40

3 Answers 3

5

The following regex should accomplish this for you, you can then save the captured groups to $path, $class, and $method.

(?:(.+)/)?(?:(.+)::)?(.+)

Here is a Rubular: http://www.rubular.com/r/1vPIhwPUub

Your php code might look something like this:

$regex = '/(?:(.+)\/)?(?:(.+)::)?(.+)/';
preg_match($regex, $controller, $matches);
$path = $matches[1];
$class = $matches[2];
$method = $matches[3];
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks! If you have any link where I can easy learn regex I will be very grateful :)
I use regular-expressions.info/reference.html as a cheat-sheet, and that website has some good tutorials. Rubular is also really useful for quickly testing your regex.
This will also match a/b, which is not a legal input!
3

This supposes that paths within the class, and the method name, can only contain letters.

The full regex is the following:

^(?:((?:[a-zA-Z]+/)*)([a-zA-Z]+)::)?([a-zA-Z]+)$

Two non capturing groups: the first one which makes all the path and class optional, the second which avoids the capture of individual path elements.

Explanation:

  • a path element is one or more letters followed by a /: [a-zA-Z]+/;
  • there may be zero or more of them: we must apply the * quantifier to the above; but the regex is not an atom, we therefore need a group. As we do not want to capture individual path elements, we use a non capturing group: (?:[a-zA-Z]+/)*;
  • we want to capture the full path if it is there, we must use a capturing group over this ((?:[a-zA-Z]+/)*);
  • the method name is one or more letters, and we want to capture it: ([a-zA-Z]+);
  • if present, it follows the path, and is followed by two semicolons: ((?:[a-zA-Z]+/)*)([a-zA-Z]+)::;
  • but all this is optional: we must therefore put a group around all this, which again we do not want to capture: (?:((?:[a-zA-Z]+/)*)([a-zA-Z]+)::)?;
  • finally, it is followed by a method name, which is NOT optional this time, and which we want to capture: (?:((?:[a-zA-Z]+/)*)([a-zA-Z]+)::)?([a-zA-Z]+);
  • and we want this to match the whole line: we need to anchor it both at the beginning and at the end, which gives the final result: ^(?:((?:[a-zA-Z]+/)*)([a-zA-Z]+)::)?([a-zA-Z]+)$

Phew.

5 Comments

second regex returns class with method, AdminClass::display. I think that regex by F.J. can be used as second
Well, it really can be done with one regex and no errors, but it will be a very long regex and require even more explanation ;) I can cook it up and explain it all if you want.
Wouldn't this also match a/b and put it all into $method?
Yes, which is why I suggested to replace .* with more restrictive regexes. But see edit.
Done. Now with the full pizzazz :p
-1
        $pieces = explode('/',$controller); 
        $path = '';
        for($i = $i<$pieces.length-1; $i++)
        {
          if($i != 0)
             $path+='/';
          $path += $pieces[$i];
        }
        $p2 = explode(  '::',$pieces[$pieces.length-1]);
        $class = $p2[0];
        $method = $p2[1];

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.