【问题标题】:.htaccess regular expression issue.htaccess 正则表达式问题
【发布时间】:2012-09-08 00:36:18
【问题描述】:

我仍然没有答案,所以我在这里发布。

我想在.htaccess文件中匹配root/language/sub/.../document形式的url,然后重写为root/sub/.../document.php?lang=language

我快要命中了,但我的正则表达式似乎没有“捕捉”输入网址。这里是:

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond ^[a-z]{2}.*$/%{REQUEST_FILENAME}\.php -f
RewriteRule ^([a-z]{2})/(.*)$ $2.php?lang=$1

有人可以指出我这里有什么问题吗?我不是 regexp 和 apache 重写方面的专家。

Tyvm

* 编辑 *

root 代表域,即mydomain.net

这里有几个例子:

mydomain.net/fr/contact

应该改写成

mydomain.net/contact.php?lang=fr

mydomain.net/en/articles/view

应该改写

mydomain.net/articles/view.php?lang=en

等等……

【问题讨论】:

    标签: regex .htaccess rewrite expression


    【解决方案1】:

    我相信你正在寻找这个配置:

    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} ^(.*/|)(en|de|fr)/(.*)$ [NC]
    RewriteCond %1%3.php -f
    RewriteRule ^(.*/|)(en|de|fr)/(.*)$ $1$3.php?lang=$2 [NC,QSA,L]
    

    解释:

    RewriteCond %{REQUEST_FILENAME} !-d
    

    检查请求的 url 是否不是目录。如果是,则不进行重写。

    RewriteCond %{REQUEST_FILENAME} ^(.*/|)(en|de|fr)/(.*)$ [NC]
    

    检查 url 内部是否包含 /xx/ 部分,其中 xxendefr 之一。标志[NC] 允许大小写字符,例如ENFr 将被接受。如果url中没有这样的“语言”部分,则不会进行重写。

    RewriteCond %1%3.php -f
    

    检查 %1%3.php 文件是否存在,其中 %1(.*/|)%3(.*) 与之前的 RewriteCond ^(.*/|)(en|de|fr)/(.*)$ 匹配。如果这样的php文件不存在,则不进行重写。

    RewriteRule ^(.*/|)(en|de|fr)/(.*)$ $1$3.php?lang=$2 [NC,QSA,L]
    

    RewriteRule中的left条件如果到了这一行就会被匹配,因为它已经用RewriteCond检查过了,所以现在它将处理重写到php文件,添加lang部分,但是因为还有[QSA]标志,它也会保留其他GET参数,所以 lang 将添加到现有参数中。标记[L] 表示这是最后一个应该应用的重写规则,并且不会再使用此 url 处理重写。

    【讨论】:

    • TYVM。现在无法检查,但肯定会在明天通知您。现在我还有最后一个问题。如果我添加一些其他 GET 变量,它们应该被添加到 lang=foo 参数中。所以它看起来我喜欢=>在字符串末尾搜索\?.*,如果是这样添加&lang=foo,否则添加?lang=foo。这样我就不会丢失 GET 行为。我想你可以在你之前添加一个RewriteRule 行吗?还是我需要为每个 RewriteRule 制作另一块 RewriteCond ?谢谢,我将您作为已接受的答案弹出^^
    • (只是为了澄清一些问题)%{REQUEST_FILENAME} 是否包含完整的 URI,即mydomain.net/fr/contact?如果不是,那么(.*/|)(第二行)对我来说毫无意义,因为 lang 将是第一个 url bit。同样,(.*/|) 中的管道 | 是什么?我知道(.*/) 匹配以/ 结尾的所有内容。疯狂猜测:可选条件?感谢您的帮助。
    • @JulienMatthey - 标志 [QSA] 将自动处理 ?/& 问题,不用担心 :) 关于你关于 (.*/|) 的问题 - 这将匹配任何结尾使用/ 之前的语言缩写,或者空字符串,那里什么都没有,所以| 是这里的 or 运算符。我希望这会有所帮助。
    • 进行了最后的编辑。除了一些小事情之外,该解决方案现在对我来说非常有效。
    【解决方案2】:

    我不确定 root 在那里做什么,你试过了吗

    RewriteRule ^root/([a-z]{2})/(.*)$ root/$2.php?lang=$1
    

    【讨论】:

    • 对不起,我本来可以更清楚的,root 实际上代表domain(即mydomain.net
    【解决方案3】:

    第二个RewriteCond 出问题了。但是你的问题很模糊。如果您的意思是您正在尝试转换

    root/foo/sub/.../something.php
    

    root/sub/.../something.php?lang=foo
    

    然后开始坐立不安:

    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^root/([^/]+)/sub/(.*)/%{REQUEST_FILENAME}$ root/sub/$2/%{REQUEST_FILENAME}?lang=$1
    

    【讨论】:

    • 感谢您的回答 - 立即测试。我刚刚做了一个编辑,所以请阅读。 root 实际上代表域,即mydomain.net。很抱歉在这里给大家带来了困扰^^
    猜你喜欢
    • 2011-12-26
    • 2020-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-25
    相关资源
    最近更新 更多