1

我正在一个小型 MVC 框架中构建一个路由器对象。它解析 url 字符串以发现控制器、操作等。它是可配置的。

目前,用户可以通过传入如下字符串来创建路由:

$this->connect('/:controller/:action/*');
$this->connect('/:controller', array('action' => 'index'));
$this->connect('/', array('controller' => 'static_pages', 'action' => 'index'));

并且路由器从这些中构建以下正则表达式:

#^(.*)/(.*)/?.*/?$#
#^(.*)/?$#
#^/$#

最后,路由器尝试根据 url 选择正确的路由。上述路由的 url 看起来像这样:

/cars/get_colors/  # will invoke cars->get_colors();
/cars/             # will invoke cars->index();
/                  # will invoke static_pages->index();

然而

我的正则表达式不正确。第一个(更具体的)表达式可以匹配第二个条件,第二个可以匹配第一个。

如果我翻转顺序以反向检查,静态页面路由有效,然后控制器索引路由有效,但控制器索引路由捕获所有更具体的路由!

更新

我正在使用正则表达式,因为用户还可以像这样连接路由:

$this->connect('/car/:action/*', array('controller' => 'cars');
$this->connect('/crazy/url/:controller/:action/*');

这将构建两个类似于此的正则表达式:

#^car/(.*)/?.*/?$#
#^crazy/url/(.*)/(.*)/?.*?$#

最后,做以下路由:

/car/get_colors/             # will invoke cars->get_colors();
/crazy/url/cars/get_colors/  # will invoke cars->get_colors();
4

2 回答 2

2

首先,您可以通过使用explode 函数将URL 拆分为段来让您的生活更轻松,而根本不使用正则表达式。

但是,如果您必须使用正则表达式,请将“.*”更改为“[^/]+”

请记住,点匹配所有内容,包括斜线。表达式“[^/]”匹配除斜杠之外的所有内容。

此外,如果您的字符串将以斜杠开头,则您需要以斜杠开头您的正则表达式。

最后,您需要使用“+”量词而不是“*”量词。

考虑这些示例,它们对应于您帖子中的正则表达式:

#^/[^/]+/[^/]+(/.*)?$#
#^/[^/]+/?$#
#^/$#
#^/car/[^/]+(/.*)?$#
#^/crazy/url/[^/]+/[^/]+(/.*)?$#
于 2011-01-19T04:31:01.850 回答
1

我已经使用 preg_replace 函数来做到这一点。

preg_replace($pattern, $replacement, $string)

preg_replace 函数执行正则表达式搜索和替换。这将搜索与模式匹配的主题并用替换替换它们。

例如http://example.com/my-planet-earth/

我说的是格式化'my-planet-earth'。在这里,$string 可以是 'My Planet Earth' 而 $urlKey 将是 'my-planet-earth'$string = "planet+*&john doe / / \ \ ^ 44 5 % 6 + - @ ku ! ~ ` this" ; $urlKey = preg_replace(array('/[^a-z0-9-]/i', '/[ ]{2,}/', '/[ ]/'), array(' ', ' ', ' -'), $string); // 输出:planet-john-doe-44-5-6---ku-this

希望这可以帮助。

于 2011-08-02T12:11:36.783 回答