在apache中反向引用正则表达式

时间:2014-01-31 18:37:02

标签: regex apache .htaccess symfony mod-rewrite

当我遇到这两行时,我正在为我的系统设置symfony框架并配置.htaccess文件以重新路由请求:

RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
RewriteRule ^(.*) - [E=BASE:%1]

这应该给我们进行重写的重写基础。 我想知道这里是如何处理$ 1的,因为它之前没有重写? 以及对此代码如何工作的一些澄清将非常感激。

1 个答案:

答案 0 :(得分:1)

$1是最后一个规则捕获组。由于mod_rewrite处理规则的方式,这有点令人困惑。鉴于你的规则:

RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
RewriteRule ^(.*) - [E=BASE:%1]

这就是mod_rewrite的作用:

  1. 我有一个URI,让我们应用这个规则
  2. 我查看RewriteRule行并检查模式:URI匹配^(。*),好的,让我们继续
  3. 现在让我们检查条件
  4. %{REQUEST_URI}::$1字符串被映射到URI和我的第一个捕获组,这发生在第2步中
  5. 条件中的模式匹配,应用规则的目标
  6. 目标是-,传递URI并应用标志
  7. 因此规则首先应用“中途”,即$1捕获组的设置方式,然后检查条件。

    请注意,如果您有:

    RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
    RewriteRule ^.* - [E=BASE:%1]
    

    $1将为空,因为规则中的模式没有捕获组。

    \2是内联后向引用,因此引用:

    this----v
    ^(/.+)/(.*)::\2$
    

    分组。

    该条件的工作原理示例是,我们有%{REQUEST_URI} /abc/foo/bar.html,并说这些规则位于/abc/目录中。这意味着条件字符串:

    %{REQUEST_URI}::$1
    

    /abc/foo/bar.html::foo/bar.html
    

    然后匹配在::之后获取部分并在::之前匹配相同的内容:

    this bit ----------v__________v
    /abc/foo/bar.html::foo/bar.html
         ^-----------^____must match this grouping
    

    因此,剩下的是第一个分组(/.+),即/abc/。现在我们有了正确的相对URI基础,存储在环境变量“BASE”中。

相关问题