Need help modifying these simple regular expressions to match urls
I'm building a router object in a small MVC framework. It parses url strings to discover controllers, actions, etc. It is configurable.
Currently, a user can create routes by passing in strings like the following:
$this->connect('/:controller/:action/*');
$this->connect('/:controller', array('action' => 'index'));
$this->connect('/', array('controller' => 'static_pages', 'action' => 'index'));
And the router builds the following regular expressions from those:
#^(.*)/(.*)/?.*/?$#
#^(.*)/?$#
#^/$#
Finally, the router tries to select the correct route based on a url. The urls for the above routes would look something like this:
/cars/get_colors/ # will invoke cars->get_colors();
/cars/ # will invoke cars->index();
/ # will invoke static_pages->index();
However
My regular expressions are not correct. The first (more specific) expression can match the second condition, and the second one can match the first.
If I flip the order to check in reverse, The static pages 开发者_StackOverflow社区route works, then the controller index route works, but the controller index rout catches all of the more specific ones!
Update
I'm using regular expressions because the user can also connect routes like these:
$this->connect('/car/:action/*', array('controller' => 'cars');
$this->connect('/crazy/url/:controller/:action/*');
Which will build two regex similar to this:
#^car/(.*)/?.*/?$#
#^crazy/url/(.*)/(.*)/?.*?$#
Finally, doing the following routing:
/car/get_colors/ # will invoke cars->get_colors();
/crazy/url/cars/get_colors/ # will invoke cars->get_colors();
First of all, you could make your life easier by using the explode function to split the URL into slugs, and not use regular expressions at all.
However, if you must use regular expressions, change ".*" to "[^/]+"
Remember, the dot matches everything, including slashes. The expression "[^/]" matches everything except slashes.
Also, you need to begin your regex with a slash if your string will begin with a slash.
Finally, you need to use the "+" quantifier instead of the "*" quantifier.
Consider these examples, which correspond to the regexes in your post:
#^/[^/]+/[^/]+(/.*)?$#
#^/[^/]+/?$#
#^/$#
#^/car/[^/]+(/.*)?$#
#^/crazy/url/[^/]+/[^/]+(/.*)?$#
I have used preg_replace function to do so.
preg_replace($pattern, $replacement, $string)
preg_replace function performs a regular expression search and replace. This will search subject for matches to pattern and replaces them with replacement.
e.g. http://example.com/my-planet-earth/
I am talking about formatting ‘my-planet-earth’. Here, $string can be ‘My Planet Earth’ and the $urlKey will be ‘my-planet-earth’$string = "planet+*&john doe / / \ \ ^ 44 5 % 6 + - @ ku ! ~ ` this"; $urlKey = preg_replace(array('/[^a-z0-9-]/i', '/[ ]{2,}/', '/[ ]/'), array(' ', ' ', '-'), $string); // outputs: planet-john-doe-44-5-6---ku-this
Hope this helps.
精彩评论