6

我目前有正在工作的 Mod Rewrite Regex:

RewriteEngine On
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^(.*/)?((?:cmd)[^/]*)/((?!(?:cmd)[.+]*)(.+)) $1?$2=$3&%1 [L]

该正则表达式采用以下 URL 并将其转换为紧随其后的 URL:

www.site.com/cmd1/param/cmd2/param2/stillparam2并将其变成www.site.com/index.php?cmd1=param&cmd2=param2/stillparam2

这很好用,但我还想创建另一个否定的前瞻断言,以确保 URL 块 - 即/texthere/参数 - 不包含下划线。无效字符串可能如下所示www.test.com/cmd/thing/getparam_valuehere:正则表达式应将 解析cmd/thing为键和值对并忽略字符串的其余部分。然后,我还将编写另一个 RewriteRule 以将带有下划线的 URL 块添加为另一个 URL 参数。将发生以下 URL 转换:

www.test.com/cmd/param1/cmd2/directory/param2/sortorder_5
www.test.com?cmd=param1&cmd2=directory/param2&sortorder=5

如果我不够清楚,请告诉我。任何帮助都会很棒。

注意:我已经尝试使用嵌套在已经存在的一个负前瞻中(?!(?!))- 并尝试|在两个负前瞻中使用一个,但两种解决方案都没有奏效。我认为也许还有其他更根本的错误?

谢谢大家。

编辑:我也尝试了以下方法 - 我真的认为它会起作用(但显然,没有!)

RewriteRule ^(.*/)?((?:cmd)[^/]*)/((?!(?:cmd)[.+]*)(?![.+]*(?:_)[.+]*)(.+)) $1?$2=$3&%1 [L]

执行以下操作:

www.test.com/cmd/param1/sortorder_1/翻译成 www.test.com?cmd=param1/sortorder_1/

当它应该变成:www.test.com?cmd=param1&sortorder=2/. 翻译/sortorder_2/成的规则&sortorder=2尚未创建,但您希望能明白我的意思)。

4

2 回答 2

1

经过大约四天的试验,我最终得到了一个与我最初预期的有所不同的解决方案。我只是将所有实际的 URL 操作删除到我的 index.php 文件中,并通过那里路由所有请求。这是我的(更干净的).htaccess 文件:

Options +FollowSymlinks
RewriteEngine On
RewriteCond %{QUERY_STRING} (.*)
RewriteRule (.*) index.php?path=$1 [QSA,L]

这是我用来解析输入的 URL 的代码块:

preg_match_all('|/([A-Za-z0-9]+) ((?!/)[A-Za-z0-9- .]*)|', $_GET['path'], $matches) ;

        // Remove all '$_GET' parameters from the actual $_GET superglobal:
        foreach($matches[0] as $k => $v) {
            $search = '/' . substr($v, 1);
            $_GET['path'] = str_replace($search, '', $_GET['path'], $count);
        }

        // Add $_GET params to URL args
        for ($i = 0; $i < count($matches[1]); $i++) {
            self::$get_arguments[$matches[1][$i]] = $matches[2][$i];
        }

        // Retrieve all 'cmd' properties from the URL and create an array with them:
        preg_match_all('~(cmd[0-9]*)/(.+?)(?=(?:cmd)|(?:\z))~', $_GET['path'], $matches);

        if (isset($matches[1][0])) {
            return self::$url_arguments = array_combine($matches[1], $matches[2]);

在这样的网址上:

http://localhost/frame_with_cms/frame/www/cmd/one/cmd2/two/cmd3/three/cmd4/four/getparam_valuepart1_valuepart2/cmd5/five/

它成功地生成了这些单独的数组,然后我用它们来处理请求:

Array
(
    [getparam] => valuepart1_valuepart2
)
Array
(
    [cmd] => one/
    [cmd2] => two/
    [cmd3] => three/
    [cmd4] => four/
    [cmd5] => five/
)

感谢所有花时间阅读和回复的人。

于 2011-07-23T00:36:57.417 回答
0

保留您的工作规则并在当前规则之前将 param_value 重写为查询字符串不是更容易吗?

就像是

RewriteRule ^(.*)?/([^_/]+)_([^/]+)/ $1/?$2=$3 [N,QSA]

应将所有 /param_value/ 部分作为 param=value 附加到查询字符串中。

小心使用 N 标志,您可能会陷入无限循环。

于 2011-07-20T09:55:26.273 回答