0

I am trying to write a simple router for PHP. And I am facing some problem. Example of the routes are as follows.

$route = []
$route['index']     = "/"; 
$route['home']      = "/home";
$route['blog']      = "/blog/[a-z]";
$route['article']   = "/article/id/[\d+]/title/[\w+]";

Now if we take the last example, I would like the regex only to look for patterns such as [\d+] and [\w+] that is it. I will use explode() to actually cross check if URL contains /blog/, /id/ and /title/. I don't want regex's help with that, but only to detect the patterns and match it.

for example. If a given $URL was dev.test/blog/id/11/title/politics

I would need some like: preg_match($route['url'], $URL)

So, now the preg_match() function knows, that after "/article/id/ there is a pattern asking only for a digit to occur, then if the digit is found it will continue parsing, or else it will show fail or 0.

I don't know much about regex to handle this complex problem.

2
  • If you have troubles with regexes, perhaps you can use something that already does it for you like Laravel? Or use a routing solution as explained in this video or this article Commented May 24, 2014 at 13:49
  • @Laoujin You are right. I could even use FastRoute. But the problem is that, for small scale project, those alternatives are overkill. Commented May 24, 2014 at 13:51

1 Answer 1

1

Your question is a little unclear, but if you want only to capture the [\d+] or [\w+] parts of the target string, you should consider using brackets to capture sub-matches, and the (?:xxx) non-capturing match, which checks for the pattern but does not add it to the array, something like:

  $route['article']   = "(?:\/article\/id\/)([\d+])(?:\/title\/)([\w+])";

This will add the matched [\d+] and [\w+] to your matches array only. You'll find them like so:

  $matches[0][0] and matches[1][0].

See http://www.regular-expressions.info/tutorial.html for an outstanding tutorial on regexes, by the way.

If you aren't sure of the values of 'article', 'id', and 'title' in advance, then you will probably at least need to be sure of the number of directories given in the url. That means as long as you know the position of the [\d+] and [\w+] entries, you could use

    $route['article'] = "(?:\/[\w+]\/[w+]\/)([\d+])(?:\/[\w+]\/)([\w+])"
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for the response. The only problem with your answer is that, I would have to also check for "/article/id/ and /title/ I don't want regex to check those. I can do it other way. All I need is that for regex to find the patterns i.e. anything inside [] and validate it if it is true or not. Hope this is clearer.
Not really - but if you mean that the values of 'article', 'id', and 'title' are dynamic and could change, then you will probably at least need to be sure of the number of directories given in the url. That means as long as you know the position of the [\d+] and [\w+] entries, you could use "(?:\/[\w+]\/[w+]\/)([\d+])(?:\/[\w+]\/)([\w+])"
I guess this is impossible to explain or do, but thanks for the effort anyway
The quick and dirty answer would be that if the first 'digit-only' pattern isn't matched, the regex will fail anyway.
OK you want to show 'fail'/ 0 if the category parts match but the rest of the regex fails? Then you'll need to check whether the categories were what you wanted and simply see if the regex succeeded. If this isn't what you meant, you would need to know the categories you were seeking in advance. In which case the regular expression would need tweaking...(?)
|

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.