问题
我编写了一个正则表达式,用于匹配 Web 应用程序上的所有常规页面。当应用程序使用 web.config 文件在 IIS 上运行时,正则表达式工作得非常好,但此后我将站点移动到 Linux 服务器,现在在 Apache 下运行。
我尝试匹配的字符串如下:
section 1/
section 1/section 2/
section 1/section 2/section 3/
我希望模式捕获每个匹配项,但有以下限制:
- 最后的"/"始终是可选的
- 我希望每个匹配项都匹配任何字符,除了前两个部分的下划线
这是我尝试过的:
^([^(?!_)'/]+)'/?([^(?!_)'/]+)?'/?([^'/]+)?'/?$
虽然上述方法在正则表达式测试器中有效,但当我将其放入 .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
不匹配,并继续评估所有其他规则。