.htaccess 重写问题,一个正则表达式适用于所有人


.htaccess Rewrite Issue, One Regex for all

问题

我编写了一个正则表达式,用于匹配 Web 应用程序上的所有常规页面。当应用程序使用 web.config 文件在 IIS 上运行时,正则表达式工作得非常好,但此后我将站点移动到 Linux 服务器,现在在 Apache 下运行。

我尝试匹配的字符串如下:

section 1/
section 1/section 2/
section 1/section 2/section 3/

我希望模式捕获每个匹配项,但有以下限制:

  1. 最后的"/"始终是可选的
  2. 我希望每个匹配项都匹配任何字符,除了前两个部分的下划线

这是我尝试过的:

^([^(?!_)'/]+)'/?([^(?!_)'/]+)?'/?([^'/]+)?'/?$

虽然上述方法在正则表达式测试器中有效,但当我将其放入 .htaccess 文件中时,它会导致我的服务器产生"内部服务器错误",而当我在我的 web.config 中运行它时则没有。

任何人都可以建议使用新模式吗?

更多信息

以下是其他请求的一些示例:

匹配示例

test/testing
SOME/REQUEST/to a page
anything can/be matched/

与示例不匹配

unless it has/an underscore_/in the/
first_section/or_second_section/

请注意,"内部服务器错误"不是由我的 .htacess 中的其他错误引起的,在我使用此特定正则表达式取消注释我的重写规则之前,一切正常。

更新

为了更清楚,这些是我希望我的正则表达式匹配的重写的进一步示例:

http://example.com/property/
http://example.com/property.php
http://example.com/property/manage/
http://example.com/property.php?request=manage
http://example.com/property/edit/1234/
http://example.com/property.php?request=edit&id=1234
http://example.com/_property/ Does NOT Match
http://example.com/property/_edit/ Does NOT Match

更新 2

以下内容正在工作,但我不喜欢我指定了允许的字符:

^([a-z0-9's]+)'/?([a-z0-9's]+)?'/?([a-z0-9's'_]+)?'/?$

正则表达式的问题在于它与自己的结果相匹配。

例如:

http://example.com/property/

将匹配为:

http://example.com/property.php

RewriteEngine将再次匹配为:

http://example.com/property.php.php

匹配为:

http://example.com/property.php.php.php

等等。。

溶液:
使最后一个斜杠为必填项或禁止在 url 上使用字符,或在 url 中添加下划线 ( _ (。

使用您的正则表达式:

^([^(?!_)'/]+)'/?([^(?!_)'/]+)?'/?([^'/]+)?'/?$

将其更改为:

^([^(?!_)'/]+)'/?([^(?!_)'/]+)?'/?([^'/]+)?'/$

与评论中一样,我提出了以下方法来解决问题:

^(?!(?:'.'.'/?)+)([^_'/]+)(?:'/([^_'/]+)(?:'/([^_'/]+))?)?'/?$

但它不会,而是一个简化版本。
为了解决这个问题,使用我在正则表达式中所说的解决方案:

禁止字符.?

^(?!(?:'.'.'/?)+)([^_'/'.'?]+)(?:'/([^_'/]+)(?:'/([^_'/]+))?)?'/?$

使'成为必须作为最后一个字符:

^(?!(?:'.'.'/?)+)([^_'/]+)(?:'/([^_'/]+)(?:'/([^_'/]+))?)?'/$

以非阻塞性黑客方式(未经测试(将_附加到文件的完整重定向:

RewriteEngine on
RewriteRule ^(?!(?:'.'.'/?)+)([^_'/]+)(?:'/([^_'/]+)(?:'/([^_'/]+))?)?'/?$ $1.php/_?request=$2&id=$3

这有将$_SERVER['PATH_INFO']设置为_的副作用。
此解决方案未经测试

任何不准确的地方,请发表评论。

编辑:

这背后的原因是我们必须打破匹配循环。
引擎验证http://example.com/property/并成功,重定向到http://example.com/property.php
如果这个也匹配,则所有子请求都将匹配,并且您有递归。
这个想法是它与http://example.com/property.php不匹配,并继续评估所有其他规则。