重写规则的正则表达式
Regular Expression for rewrite rule
我正在尝试将一个开源论坛集成到我的 WordPress 安装中,如果我能让重写规则起作用,我可以想出接下来的步骤,到目前为止我有以下内容:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^forum/qa\-theme/(.*) forum-embed/qa-theme/ [QSA,L]
RewriteRule ^forum/qa\-content/(.*) forum-embed/qa-content/ [QSA,L]
RewriteRule ^forum/([\w]+)$ forum/?url= [QSA,L]
</IfModule>
前两个规则有效,但最后一个规则,我已经尝试了对该正则表达式的各种更改 - 我想在 [=11= 之后采用 任何 ] 并将其作为 url
参数放入查询字符串中。我确定我对表达方式小心翼翼 - 我错过了什么?
提前致谢!
编辑
It's also not clear how you are avoiding conflicts with the WordPress front-controller? Presumably you are placing these directives at the top of the .htaccess file, before the # BEGIN WordPress section? However, it may be simpler to create another .htaccess file inside the /forum subdirectory instead and this will (by default) override the WordPress directives.
一个合理的观点,是的,我把它放在 # BEGIN WordPress 上面,但我会在论坛目录中创建一个 .htaccess。
You say you've "tried all sorts of changes to this regular expression", but this regex certainly won't match your first example. The \w shorthand character class excludes slashes and hyphens.
是的,这是一个不好的例子来说明我的问题,但我也试过:
- ^论坛/(.+)$
- ^论坛/([a-z-A-Z-0-9-/]+)$
/forum/ is presumably a filesystem directory - this itself can't handle the request, it requires further rewriting to an actual file
我不明白 -- 前两个规则有效,我可以导航到所有页面,包括 forum/
-- index.php 是配置中的默认文件,为什么必须这样规则是例外吗?
RewriteRule ^forum/([\w]+)$ forum/?url= [QSA,L]
Example 1: forum/2/test-question => forum/?url=2/test-question
你说你“尝试了对这个正则表达式的各种改变”,但这个正则表达式肯定不符合你的第一个例子。 \w
shorthand 字符 class 不包括斜杠和连字符。如果你想匹配“whatever comes after forum/
”,那么你可以使用 (.+)
(like 你之前的例如,除了 +
而不是 *
以避免重写循环,即避免匹配 /forum/
)。例如:
RewriteRule ^forum/(.+) forum/?url= [QSA,L]
但是,forum/?url=whatever
仍然不是一个有效的终点(正如@RavinderSingh13 在评论中指出的那样)。 /forum/
大概是一个文件系统目录 - 这本身无法处理请求,它需要进一步重写到一个实际文件(也许你期望 mod_dir 发出对 DirectoryIndex
的子请求? ).比如应该是/forum/index.php?url=whatever
?
也不清楚您是如何避免与 WordPress 前端控制器发生冲突的?大概您将这些指令放在 .htaccess
文件的顶部,在 # BEGIN WordPress
部分之前?但是,在 /forum
子目录中创建另一个 .htaccess
文件可能更简单,这将(默认情况下)覆盖 WordPress 指令。
您应该删除 <IfModule>
包装器,因为此处不需要它。
更新:
/forum/ is presumably a filesystem directory - this itself can't handle the request, it requires further rewriting to an actual file
我不明白 -- 前两个规则有效,我可以导航到所有页面,包括 forum/ -- index.php 是配置中的默认文件,为什么这个规则必须是一个异常?
我们不知道前两个规则预期处理什么请求,但我假设它们只是重写静态文件 ?
当您请求 目录 /forum/
时,mod_dir 必须稍后发出对 DirectoryIndex
文档的子请求。当您将请求重写为 /forum
时,mod_dir 稍后仍必须执行此附加处理。同时,.htaccess
和 /forum/
中的重写处理循环通过重写引擎传回。这可能有效也可能无效 - 它可能导致其他冲突 - 至少它是 additional/unnecessary 处理。您应该直接重写处理请求的文件,以减少这种额外的处理。同样,WordPress 代码块将请求重写为 /index.php
,而不是 /
。
澄清一下,只有当您请求 /forum/
时,才会触发上述指令,并且 mod_dir 发出 /forum/index.php
的子请求。没有 url
参数。
更新指令
但是,如果重写为 /forum/index.php
,您将需要额外的检查以避免 /forum/index.php
被同一规则捕获并导致重写循环(500 错误)。
例如,请尝试以下操作:
RewriteRule ^forum/index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^forum/(.+) forum/index.php?url= [QSA,L]
检查 REQUEST_FILENAME
的 条件 可能是可选的,具体取决于此目录树是否提供任何静态资源?
或者,如果您的网址不包含点,那么您可以使用限制性更强的正则表达式来避免匹配包含点的网址。例如:
RewriteRule ^forum/([^.]+)$ forum/index.php?url= [QSA,L]
/forum/.htaccess
如果将这些指令移动到 /forum/.htaccess
文件中,您将按如下方式重写它们(并完全删除 RewriteBase
指令):
RewriteEngine On
RewriteRule ^qa-theme/(.*) /forum-embed/qa-theme/ [L]
RewriteRule ^qa-content/(.*) /forum-embed/qa-content/ [L]
RewriteRule ^([^.]+)$ index.php?url= [QSA,L]
前两个指令不需要 QSA
标志,因为默认情况下会传递查询字符串。 (虽然如果这些是重写静态资源那么你不会期望传递查询字符串?)
不需要反斜杠转义正则表达式中的连字符,因为它在字符外使用时没有特殊含义 class。同样,点在 内部 字符 class 中使用时没有特殊含义,因此在上面的最后一条规则中不需要反斜杠转义。
我正在尝试将一个开源论坛集成到我的 WordPress 安装中,如果我能让重写规则起作用,我可以想出接下来的步骤,到目前为止我有以下内容:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^forum/qa\-theme/(.*) forum-embed/qa-theme/ [QSA,L]
RewriteRule ^forum/qa\-content/(.*) forum-embed/qa-content/ [QSA,L]
RewriteRule ^forum/([\w]+)$ forum/?url= [QSA,L]
</IfModule>
前两个规则有效,但最后一个规则,我已经尝试了对该正则表达式的各种更改 - 我想在 [=11= 之后采用 任何 ] 并将其作为 url
参数放入查询字符串中。我确定我对表达方式小心翼翼 - 我错过了什么?
提前致谢!
编辑
It's also not clear how you are avoiding conflicts with the WordPress front-controller? Presumably you are placing these directives at the top of the .htaccess file, before the # BEGIN WordPress section? However, it may be simpler to create another .htaccess file inside the /forum subdirectory instead and this will (by default) override the WordPress directives.
一个合理的观点,是的,我把它放在 # BEGIN WordPress 上面,但我会在论坛目录中创建一个 .htaccess。
You say you've "tried all sorts of changes to this regular expression", but this regex certainly won't match your first example. The \w shorthand character class excludes slashes and hyphens.
是的,这是一个不好的例子来说明我的问题,但我也试过:
- ^论坛/(.+)$
- ^论坛/([a-z-A-Z-0-9-/]+)$
/forum/ is presumably a filesystem directory - this itself can't handle the request, it requires further rewriting to an actual file
我不明白 -- 前两个规则有效,我可以导航到所有页面,包括 forum/
-- index.php 是配置中的默认文件,为什么必须这样规则是例外吗?
RewriteRule ^forum/([\w]+)$ forum/?url= [QSA,L]
Example 1: forum/2/test-question => forum/?url=2/test-question
你说你“尝试了对这个正则表达式的各种改变”,但这个正则表达式肯定不符合你的第一个例子。 \w
shorthand 字符 class 不包括斜杠和连字符。如果你想匹配“whatever comes after forum/
”,那么你可以使用 (.+)
(like 你之前的例如,除了 +
而不是 *
以避免重写循环,即避免匹配 /forum/
)。例如:
RewriteRule ^forum/(.+) forum/?url= [QSA,L]
但是,forum/?url=whatever
仍然不是一个有效的终点(正如@RavinderSingh13 在评论中指出的那样)。 /forum/
大概是一个文件系统目录 - 这本身无法处理请求,它需要进一步重写到一个实际文件(也许你期望 mod_dir 发出对 DirectoryIndex
的子请求? ).比如应该是/forum/index.php?url=whatever
?
也不清楚您是如何避免与 WordPress 前端控制器发生冲突的?大概您将这些指令放在 .htaccess
文件的顶部,在 # BEGIN WordPress
部分之前?但是,在 /forum
子目录中创建另一个 .htaccess
文件可能更简单,这将(默认情况下)覆盖 WordPress 指令。
您应该删除 <IfModule>
包装器,因为此处不需要它。
更新:
/forum/ is presumably a filesystem directory - this itself can't handle the request, it requires further rewriting to an actual file
我不明白 -- 前两个规则有效,我可以导航到所有页面,包括 forum/ -- index.php 是配置中的默认文件,为什么这个规则必须是一个异常?
我们不知道前两个规则预期处理什么请求,但我假设它们只是重写静态文件 ?
当您请求 目录 /forum/
时,mod_dir 必须稍后发出对 DirectoryIndex
文档的子请求。当您将请求重写为 /forum
时,mod_dir 稍后仍必须执行此附加处理。同时,.htaccess
和 /forum/
中的重写处理循环通过重写引擎传回。这可能有效也可能无效 - 它可能导致其他冲突 - 至少它是 additional/unnecessary 处理。您应该直接重写处理请求的文件,以减少这种额外的处理。同样,WordPress 代码块将请求重写为 /index.php
,而不是 /
。
澄清一下,只有当您请求 /forum/
时,才会触发上述指令,并且 mod_dir 发出 /forum/index.php
的子请求。没有 url
参数。
更新指令
但是,如果重写为 /forum/index.php
,您将需要额外的检查以避免 /forum/index.php
被同一规则捕获并导致重写循环(500 错误)。
例如,请尝试以下操作:
RewriteRule ^forum/index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^forum/(.+) forum/index.php?url= [QSA,L]
检查 REQUEST_FILENAME
的 条件 可能是可选的,具体取决于此目录树是否提供任何静态资源?
或者,如果您的网址不包含点,那么您可以使用限制性更强的正则表达式来避免匹配包含点的网址。例如:
RewriteRule ^forum/([^.]+)$ forum/index.php?url= [QSA,L]
/forum/.htaccess
如果将这些指令移动到 /forum/.htaccess
文件中,您将按如下方式重写它们(并完全删除 RewriteBase
指令):
RewriteEngine On
RewriteRule ^qa-theme/(.*) /forum-embed/qa-theme/ [L]
RewriteRule ^qa-content/(.*) /forum-embed/qa-content/ [L]
RewriteRule ^([^.]+)$ index.php?url= [QSA,L]
前两个指令不需要 QSA
标志,因为默认情况下会传递查询字符串。 (虽然如果这些是重写静态资源那么你不会期望传递查询字符串?)
不需要反斜杠转义正则表达式中的连字符,因为它在字符外使用时没有特殊含义 class。同样,点在 内部 字符 class 中使用时没有特殊含义,因此在上面的最后一条规则中不需要反斜杠转义。