Mod Rewrite Regex - 多个负面前瞻

时间:2011-07-17 22:34:54

标签: php regex apache mod-rewrite negative-lookahead

我目前有工作的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的规则,但您可以希望看到我的意思。

2 个答案:

答案 0 :(得分:1)

经过大约四天的实验,我得到的解决方案与我原先预期的有所不同。我只是删除了对index.php文件的所有实际URL操作,并通过那里路由所有请求。这是我的(更清洁).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/
)

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

答案 1 :(得分:0)

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

这样的东西

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

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

使用N标志时,请注意无限循环。