【问题标题】:Apache RewriteRule: Is the pattern "." a special case?Apache RewriteRule:是模式“。”一个特例?
【发布时间】:2011-01-16 11:23:36
【问题描述】:

我见过 无数 RewriteRule 示例,大致如下:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

这里的目的是不由真实文件支持的 URI 将由 CMS 处理,通过 /index.php 连接。例如,WordPress 在其standard(?) .htaccess file 中使用了这种技术。

但是,正则表达式没有任何意义。不讨论匹配的主题字符串(但请参阅官方 Apache RewriteRule 文档中的“匹配的内容?”),正则表达式 . 应该只匹配 第一个字符 !但是,它的行为与.* 相同,即匹配整个 主题字符串。设置RewriteLogLevel 5,我得到..* 的相同结果和日志条目。

我只能得出结论,带有 . 模式的 RewriteRule 是特殊情况的并且匹配整个字符串(例如 .*),而不是通过 RegExp 引擎按原样处理。但是,我还没有在任何地方看到这个记录。是文档不足,还是我完全遗漏了什么?

谢谢!

【问题讨论】:

    标签: apache wordpress .htaccess mod-rewrite


    【解决方案1】:

    哦,呃……当我意识到自己只是瘸腿时,我讨厌。

    我正在从程序员的思维方式接近 mod-rewrite。在我知道的每个正则表达式库中,替换仅替换主题字符串的 匹配部分。所以例如

    $ perl
    $hello = "hello";
    $hello =~ s/lo/p/;
    print "$hello\n";
    ^D
    

    展示

    help
    

    然而,在 mod-rewrite 中,我们并没有操纵字符串。如果 URI 完全匹配,我们完全将其替换为 Substitution。因此,仅仅一个匹配 (".") 就足以将 整个字符串 替换为 /index.php。

    Apache docs 有点说明这一点,但并没有那么有力地纠正处于错误顶空的人:

    重写规则的替换是 替换原来的字符串 与 Pattern 匹配的 URL 路径。

    【讨论】:

      【解决方案2】:

      默认情况下,正则表达式在任何地方匹配输入字符串。 您认为 . 应该只匹配第一个字符的假设是错误的:它将匹配 any 字符,第一个,最后一个,第 24 个字符,没关系:任何非空字符串将匹配。 .* 有一个微妙的区别:它会匹配任何字符串,甚至是零长度的字符串。

      要获得您认为的行为,请使用^(匹配字符串开头)和$(匹配结尾)。

      总结:

      . 将匹配任何至少包含一个字符的字符串
      .* 将匹配任何字符串,即使是空字符串
      ^.$ 将仅匹配一个字符长的字符串
      ^.*$ 将匹配单行模式下的任意字符串,多行模式下的任意一行

      【讨论】:

      • 谢谢你,朱利安。也许我的问题不够清楚。当我写“正则表达式 . 应该只匹配第一个字符!”时,我并不是说我希望它只匹配第一个字符(相反,它必须匹配整个字符串)。我也不是指句法上的“。”只匹配其主题字符串的第一个字符(如“^.”)。而是我的意思是在实践中当模式“。”应用于字符串“abcd”,匹配为“a”。我认为我们在此处进行 s///g 全局匹配(对于那些习惯于 Perl 语法的人)。
      猜你喜欢
      • 2016-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多