正则表达式匹配 .htaccess 中的一系列文件类型
我想这将是一个愚蠢的问题,但我不明白这里发生了什么。我想通过 .htaccess 文件中的正则表达式来匹配一组特定的 URI。
我想要以下
- 所有不包含 .
- 所有以 .htm / .html 结尾的文件
- 所有以 .php 结尾的文件
所以:
^[^.]+$
可以匹配 URI 中没有点的所有文件。
\.html?$
匹配所有 .html / .htm 文件
(^[^.]+$)|(\.html?$)
似乎可以结合使用,但
(^[^.]+$)|(\.html?$)|(\.php$)
无法将内容与以 php 结尾的匹配文件结合起来。例如 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:
测试下面的第一个答案后我发现使用 simple:
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,他通过下面的评论帮助我解决了这个问题。
这确实是一个愚蠢的问题。发生的情况如下:
rewrite.log:
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]
再次:谢谢大家。
this is going to be a silly question I guess but I don't see what is going on here. I want to match a certain set of URIs via a regex in an .htaccess file.
I want the following
- All files that don't contain a .
- all files ending on .htm / .html
- all files ending on .php
So:
^[^.]+$
works to match all files with no dot in the URI.
\.html?$
matches all .html / .htm files
(^[^.]+$)|(\.html?$)
seems to work combining both
(^[^.]+$)|(\.html?$)|(\.php$)
fails to combine things with the match files ending on php case. test.jpg for example matches now while it should not.
I must be missing something obvious.
What is it? Thanks.
Update: here is the entire context I was using:
### REWRITE RULES ###
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (^[^.]+$)|(\.html?$)|(\.php$) bootstrap.php [L,QSA]
bootstrap.php contains:
echo "testing bootstrap";
Querying a non existing .jpg
http://localhost/test.jpg
gives me this output:
testing bootstrap
...
Update 2:
After testing the first answer below I found that using the simple:
RewriteRule \.php$ bootstrap.php [L,QSA]
fails in the same way as the above. It matches test.jpg. There is nothing crazy in the server configuration or .htaccess file though... This is all there is in the .htaccess file except what I posted already:
AddType application/x-httpd-php .html
AddType application/x-httpd-php .xml
DirectoryIndex index.php
ErrorDocument 404 /errors/404.php
Answer: (Couldn't anwer my own question for 8 more hours...)
Thanks everyone for helping me out.
Special thanks to @mario who helped me solve this by his comment below.
It was a silly question indeed. Here is what was happening:
rewrite.log:
strip per-dir prefix: D:/Web_Root/test.jpg -> test.jpg
applying pattern '\.php
So the problem was that my 404 document ended on *.php which was why *.jpg matched for the not found file. Ah Bats, I would have searched this one for a long time...
So this does it:
RewriteRule ([^4]?[^0]?[^4]\.php) bootstrap.php [L,QSA]
Well, the complete question's answer is:
RewriteRule (^[^.]+$)|(\.html?$)|([^4]?[^0]?[^4]\.php) bootstrap.php [L,QSA]
Again: Thanks people.
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
So the problem was that my 404 document ended on *.php which was why *.jpg matched for the not found file. Ah Bats, I would have searched this one for a long time...
So this does it:
Well, the complete question's answer is:
Again: Thanks people.
to uri 'errors/404.php'
RewriteCond: input='D:/Web_Root/errors/404.php' pattern='!-d' => matched
rewrite 'errors/404.php' -> 'bootstrap.php'
...
So the problem was that my 404 document ended on *.php which was why *.jpg matched for the not found file. Ah Bats, I would have searched this one for a long time...
So this does it:
Well, the complete question's answer is:
Again: Thanks people.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
当 mod_rewrite 规则出错时,它有时有助于启用
RewriteLog
。它需要在httpd.conf
或VirtualHost
部分进行配置,因此需要一些工作。但 Apache 会列出它执行的顺序和处理操作以及 URL。这有助于查看 Apache 是否理解正则表达式并且其行为是否正常。请注意,如果实际错误源是
Alias
和Redirect
规则,甚至是FileMatch
部分,它有时可能会保持为空。在这种情况下,error.log
甚至只是access.log
可能会包含一些提示。如果一切都失败,您可能会幸运地暂时启用
Nanoweb
而不是 Apache。它带有类似的mod_rewrite
实现,但是使用 PHPpreg_match
PCRE 后端。 (没有告诉我为什么知道这一点。)When mod_rewrite rules go wrong, it sometimes helps to enable the
RewriteLog
. It needs to be configured in thehttpd.conf
orVirtualHost
section and thus is a bit effort. But there Apache will list the order and processing actions it performs and the URL. This can be helpful to see if the regex is understood by Apache and does behave as it should.Note that it can sometimes remain empty - if the actual error source are
Alias
andRedirect
rules or evenFileMatch
sections. In this case theerror.log
or even just theaccess.log
might contain some hints however.If all fails, you might have luck with temporarily enabling
Nanoweb
instead of Apache. It comes with a similarmod_rewrite
implementation, which however uses PHPspreg_match
PCRE backend. (Not telling why I know that.)好的,看来您的重写正在工作...您可以看到“测试引导程序”消息。 “无法修改标头”警告与此无关。这意味着您正在尝试执行类似 session_start() 或 header() 之类的操作,或者在输出某些内容之后(可能是“测试引导”消息)
okay, so it looks like your rewrite IS working...you can see your "testing bootstrap" message. That "cannot modify header" warning is not related. That means you are trying to do something like session_start() or header() or something after you already output something (probably that 'testing bootstrap' message)
这对你有用吗?
*编辑:
我误解了你想要做什么。这个怎么样:
Does this work for you?
*Edit:
I misunderstood what you were trying to do. What about this: