正则表达式匹配 .htaccess 中的一系列文件类型

Posted

技术标签:

【中文标题】正则表达式匹配 .htaccess 中的一系列文件类型【英文标题】:regex to match a series of file types in .htaccess 【发布时间】:2011-08-29 22:18:37 【问题描述】:

我猜这将是一个愚蠢的问题,但我不明白这里发生了什么。我想通过 .htaccess 文件中的正则表达式匹配一组特定的 URI。

我想要以下

所有不包含 . 的文件 所有以 .htm / .html 结尾的文件 所有以 .php 结尾的文件

所以:

^[^.]+$

用于匹配 URI 中没有点的所有文件。

\.html?$

匹配所有 .html / .htm 文件

(^[^.]+$)|(\.html?$)

似乎可以将两者结合起来

(^[^.]+$)|(\.html?$)|(\.php$)

无法将内容与以 php case 结尾的匹配文件结合起来。例如 test.jpg 现在匹配,而它不应该匹配。

我一定遗漏了一些明显的东西。 它是什么?谢谢。

更新:这是我使用的整个上下文:

### REWRITE RULES ###
RewriteEngine on
RewriteBase /
RewriteCond %REQUEST_FILENAME !-d
RewriteRule (^[^.]+$)|(\.html?$)|(\.php$) bootstrap.php [L,QSA]

bootstrap.php 包含:

echo "testing bootstrap";

查询一个不存在的.jpg

http://localhost/test.jpg

给我这个输出:

testing bootstrap
...

更新 2:

在测试了下面的第一个答案后,我发现使用简单:

RewriteRule \.php$ bootstrap.php [L,QSA]

以与上述相同的方式失败。它匹配 test.jpg。在服务器配置或 .htaccess 文件中没有什么疯狂的......这就是 .htaccess 文件中的所有内容,除了我已经发布的内容:

AddType application/x-httpd-php .html
AddType application/x-httpd-php .xml
DirectoryIndex index.php
ErrorDocument 404 /errors/404.php

答案:(再过 8 个小时都无法回答我自己的问题...)

感谢大家帮助我。 特别感谢@mario,他通过下面的评论帮助我解决了这个问题。 这确实是一个愚蠢的问题。这是发生了什么:

重写日志:

strip per-dir prefix: D:/Web_Root/test.jpg -> test.jpg
applying pattern '\.php$' to uri 'test.jpg'
pass through D:/Web_Root/test.jpg
strip per-dir prefix: D:/Web_Root/errors/404.php -> errors/404.php
applying pattern '\.php$' to uri 'errors/404.php'
RewriteCond: input='D:/Web_Root/errors/404.php' pattern='!-d' => matched
rewrite 'errors/404.php' -> 'bootstrap.php'
...

所以问题是我的 404 文档以 *.php 结尾,这就是 *.jpg 匹配未找到文件的原因。啊蝙蝠,我会搜索这个很长时间......

这样就可以了:

RewriteRule ([^4]?[^0]?[^4]\.php) bootstrap.php [L,QSA]

嗯,完整的问题答案是:

RewriteRule (^[^.]+$)|(\.html?$)|([^4]?[^0]?[^4]\.php) bootstrap.php [L,QSA]

再次感谢大家。

【问题讨论】:

这可以写得更好一些,但 test.jpg 仍然不匹配......除非你有像“test.jpg.php”之类的东西......你在尝试什么使用模式? (附注 - 我没有投票结束这个话题..不知道谁做过,但这个问题与 SO 相关......) 我在问题中添加了有关我如何使用它的信息。感谢您查看此内容。 很难说。您可能想尝试RewriteLog 来找出答案。 (我相信 mod_rewrite 使用标准的 posix 正则表达式函数,所以它可能不支持 ^ 和 $ 替代品。) @mario 非常感谢您的建议。我不知道这个日志选项。 @mario 由于您的评论,我解决了它。请参阅上面的编辑。如果您将评论作为答案发布,我很乐意接受。 【参考方案1】:

[好吧,这不是这里的具体解决方案,但我会做一个虚假的答案。]

当 mod_rewrite 规则出错时,启用RewriteLog 有时会有所帮助。它需要在httpd.confVirtualHost 部分进行配置,因此有点费力。但是 Apache 会列出它执行的顺序和处理操作以及 URL。这有助于查看 Apache 是否理解 regex 并按其应有的方式运行。

请注意,它有时会保持为空 - 如果实际错误源是 AliasRedirect 规则,甚至是 FileMatch 部分。在这种情况下,error.log 甚至只是 access.log 可能包含一些提示。

如果一切都失败了,你可能会幸运地暂时启用Nanoweb 而不是 Apache。它带有类似的mod_rewrite 实现,但是使用PHP preg_match PCRE 后端。 (不告诉我为什么我知道。

【讨论】:

【参考方案2】:

好的,看来您的重写工作正常...您可以看到“测试引导”消息。 “无法修改标题”警告不相关。这意味着您正在尝试执行 session_start() 或 header() 之类的操作,或者在您已经输出某些内容(可能是“测试引导”消息)之后执行某些操作

【讨论】:

当然可以。但它绝对不适用于“test.jpg”调用。警告确实无关。我把它排除在外。感谢您指出这令人困惑。【参考方案3】:

这对你有用吗?

(^[^.]+$)|\.(html?$|php$)

*编辑: 我误解了你想做什么。这个呢:

RewriteCond %REQUEST_FILENAME !-d
RewriteCond %REQUEST_FILENAME ^[^.]+$ [OR]
RewriteCond %REQUEST_FILENAME ^.*\.(html?|php)$
RewriteRule ^(.*)$ bootstrap.php [L,QSA]

【讨论】:

不,它给出了相同的结果。你上面有一个'('太少或一个')'太多。但是 ((^[^.]+$)|\.(html?$|php$)) 和 (^[^.]+$)|\.(html?$|php$) 仍然匹配 test.jpg在上面详述的场景中。一旦我删除了“|php”,事情就会再次起作用。如果我使用“php”而不是“html”?那又不行了…… 感谢回复,我解决了,见原问题的补充。

以上是关于正则表达式匹配 .htaccess 中的一系列文件类型的主要内容,如果未能解决你的问题,请参考以下文章

伪静态规则写法RewriteRule-htaccess详细语法使用

正则表达式的一点奇怪

将一个系列中的数字添加到同一数据框中的一系列字母,可能使用正则表达式

剑指offer系列26--正则表达式匹配

LinuxShell——正则表达式

20170502 匹配单个字符串