Apache RewriteRule 不使用否定模式替换 RewriteCond 捕获组

标签 apache .htaccess mod-rewrite

我熟悉 Regexp、RewriteCond 和 RewriteRule。

问题是我的 RewriteRule 没有替换最后一个 RewriteCond 中的捕获组。

Apache v2.4.10

RewriteCond %{REQUEST_URI} !(apps/)?index.php
RewriteRule ^(apps/)?(.*)$ /%1index.php?$2 [QSA,NC,L]

根据文档,%1 应替换为 RewriteCond 中的捕获组:(apps/),但事实并非如此。

Apache 调试:

RewriteCond: input='/apps/x/y' pattern='!(apps/)?index.php' => matched
rewrite 'x/y' -> '/index.php?x/y'

调试确实表明 Cond 匹配,因此它应该捕获该组。

它表示输入包含 apps/ 部分。

但是,重写并没有考虑它......

按如下方式添加额外的(无用的)RewriteCond 来强制匹配,但不使用 ! 否定模式! 确实 使其起作用,因此捕获组确实被捕获并且替换:

RewriteCond %{REQUEST_URI} !(apps/)?index.php
RewriteCond %{REQUEST_URI} ^/(apps/)?
RewriteRule ^(apps/)?(.*)$ /%1index.php?$2 [QSA,NC,L]

有什么想法吗?这是带有 ! 的正则表达式的某种优化,这样它就不会评估捕获组吗?这应该被报告为错误吗?它在任何地方都有记录吗?

最佳答案

否定模式不会捕获任何内容,因为根据定义,模式不匹配,因此没有任何内容可捕获。文档中提到了这一点,但如果您仔细考虑一下,它也是显而易见的。本来不存在的东西怎么可能被捕获呢?捕获来自匹配,而不是来自正则表达式的内容。它可以包括通配符或其他可变模式。就你而言,事实并非如此。如果是的话,它会在捕获中放入什么?没有什么可以用的。如果没有,您已经知道它是什么,因此无需“捕获”它。没有地方可以使用否定模式进行捕获。

来自文档:

Note

When using the NOT character to negate a pattern, you cannot include grouped wildcard parts in that pattern. This is because, when the pattern does NOT match (ie, the negation matches), there are no contents for the groups. Thus, if negated patterns are used, you cannot use $N in the substitution string!

以上来自RewriteRule部分,但根据定义,对于否定的 RewriteCond 模式显然是相同的。

关于Apache RewriteRule 不使用否定模式替换 RewriteCond 捕获组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41731092/

相关文章:

https 站点的 Apache 反向代理给出 (70014) 找到文件结尾 :

apache - Monit 仅对 HTTPS 网站使用 HTTP

.htaccess - 反向代理 htaccess

wordpress - 用于 Wordpress 的 htaccess 脚本将选定页面作为 https

PHP 代码确定用户是否被 301 重定向到我的网站

spring - Apache + SpringBoot + SSL

centos - 如何在 iptables 中为 SVN 打开端口?

PHP - .htaccess 干净的 URL 不起作用

.htaccess 重写带问号的 URL "?"

regex - RewriteCond 文件存在