【问题标题】:Regular Expression for rewrite rule重写规则的正则表达式
【发布时间】:2021-10-26 03:19:38
【问题描述】:

我正在尝试将一个开源论坛集成到我的 WordPress 安装中,如果我可以让重写规则起作用,我可以弄清楚接下来的步骤,到目前为止我有以下内容:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^forum/qa\-theme/(.*) forum-embed/qa-theme/$1 [QSA,L]
RewriteRule ^forum/qa\-content/(.*) forum-embed/qa-content/$1 [QSA,L]
RewriteRule ^forum/([\w]+)$ forum/?url=$1 [QSA,L]
</IfModule>

前两条规则有效,但最后一条,我已经尝试了对这个正则表达式的各种更改 - 我想把 forum/ 之后的 whatever 放到一个查询字符串作为url 参数。我确定我是在小心翼翼地表达 - 我错过了什么?

提前致谢!

编辑

还不清楚您是如何避免与 WordPress 前端控制器发生冲突的?大概您将这些指令放在 .htaccess 文件的顶部,在 # BEGIN WordPress 部分之前?但是,在 /forum 子目录中创建另一个 .htaccess 文件可能更简单,这将(默认情况下)覆盖 WordPress 指令。

一个合理的观点,是的,我把它放在# BEGIN WordPress 上面,但我会在论坛目录中创建一个 .htaccess。

您说您“尝试了对此正则表达式的各种更改”,但此正则表达式肯定与您的第一个示例不匹配。 \w 速记字符类不包括斜杠和连字符。

的确,这是一个不好的例子,无法说明我对我的问题的态度,但我也尝试过:

  • ^forum/(.+)$
  • ^forum/([a-z-A-Z-0-9-/]+)$

/forum/ 可能是一个文件系统目录 - 这本身无法处理请求,它需要进一步重写为实际文件

我不明白——前两条规则有效,我可以导航到所有页面,包括forum/——index.php 是配置中的默认文件,为什么这条规则必须例外?

【问题讨论】:

  • 感谢您分享您的努力,您能否提及链接示例,例如 FROM which link TO 您要重写的链接?这将使我们更好地理解您的问题,谢谢。
  • 当然。示例 1:forum/2/test-question => forum/?url=2/test-question 示例 2:forum/ask => forum/?url=ask 希望对您有所帮助。
  • 好的,还有几个问题。第一 - 我们如何知道(通过条件)哪些规则 2 参数应该作为查询字符串发送(您的第一个 URL 示例)以及在哪里只发送 1 个参数(作为查询字符串)? forum/ask =&gt; forum/?url=ask 也没有文件名,它将在后端提供服务,如 index.php 等?请确认一次,我会尽力帮助您。
  • 不确定我是否 100% 理解你,但我真的只需要将整个组 ($1) 作为查询字符串 (url) 的唯一参数 - 我可以分解值根据需要接收页面。这有帮助吗?
  • 对不起,我还不清楚。我这边有两个问题。 1st-您在哪里收集查询字符串到您在后端发送的文件,例如:(index.php OR index.html 等)?第二-您说您希望将 $1 的所有内容作为查询字符串发送,但是从哪里决定 $1 具有什么价值?就像在 URL forum/2/test-question 中一样,它向查询字符串发送 2 个值,但在 URL forum/ask 中,它向查询字符串发送 1 个值。请就这些问题告诉我一次,谢谢。

标签: mod-rewrite apache2


【解决方案1】:
RewriteRule ^forum/([\w]+)$ forum/?url=$1 [QSA,L]

示例 1:forum/2/test-question => forum/?url=2/test-question

您说您“尝试了对此正则表达式的各种更改”,但此正则表达式肯定与您的第一个示例不匹配。 \w 速记字符类不包括斜线和连字符。如果你想匹配“forum/”之后的“whatever”,那么你可以使用(.+)like你之前的例子,除了+而不是@987654326 @ 避免重写循环,即避免匹配/forum/)。例如:

RewriteRule ^forum/(.+) forum/?url=$1 [QSA,L]

然而,forum/?url=whatever 仍然不是一个有效的端点(正如@RavinderSingh13 在 cmets 中指出的那样)。 /forum/ 可能是一个文件系统目录 - 它本身无法处理请求,它需要进一步重写为实际文件(也许您希望 mod_dir 为 DirectoryIndex 发出子请求?)。比如应该是/forum/index.php?url=whatever吗?

还不清楚您是如何避免与 WordPress 前端控制器发生冲突的?大概您将这些指令放在.htaccess 文件的顶部,在# BEGIN WordPress 部分之前?但是,在 /forum 子目录中创建另一个 .htaccess 文件可能更简单,这将(默认情况下)覆盖 WordPress 指令。

您应该删除 &lt;IfModule&gt; 包装器,因为这里不需要它。


更新:

/forum/ 可能是一个文件系统目录 - 这本身无法处理请求,它需要进一步重写为实际文件

我不明白 -- 前两条规则有效,我可以导航到所有页面,包括论坛/ -- index.php 是配置中的默认文件,为什么这条规则必须例外?

我们不知道前两条规则应该处理什么请求,但我假设它们只是重写静态文件

当您请求 目录 /forum/ 时,mod_dir 必须稍后为 DirectoryIndex 文档发出子请求。当您将请求重写为/forum 时,mod_dir 以后仍必须执行此附加处理。与此同时,.htaccess/forum/ 中的重写处理循环通过重写引擎传回。这可能会或可能不会起作用 - 它可能导致其他冲突 - 至少它是额外/不必要的处理。您应该直接重写处理请求的文件以取消此附加处理。以同样的方式,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=$1 [QSA,L]

检查REQUEST_FILENAME条件 可能是可选的,具体取决于此目录树是否提供任何静态资源?

或者,如果您的网址不包含点,那么您可以使用更严格的正则表达式来避免匹配包含点的网址。例如:

RewriteRule ^forum/([^.]+)$ forum/index.php?url=$1 [QSA,L]

/forum/.htaccess

如果将这些指令移动到 /forum/.htaccess 文件,您将按如下方式重写它们(并完全删除 RewriteBase 指令):

RewriteEngine On

RewriteRule ^qa-theme/(.*) /forum-embed/qa-theme/$1 [L]
RewriteRule ^qa-content/(.*) /forum-embed/qa-content/$1 [L]
RewriteRule ^([^.]+)$ index.php?url=$1 [QSA,L]

前两个指令不需要QSA 标志,因为默认情况下会传递查询字符串。 (尽管如果这些是重写静态资源,那么您不会期望传递查询字符串?)

不需要对正则表达式中的连字符进行反斜杠转义,因为它在字符类之外使用时没有特殊含义。同样,点在内部字符类中使用时没有特殊含义,因此不需要在上面的最后一条规则中进行反斜杠转义。

【讨论】:

  • @Jester 我已经用一些修改后的指令更新了我的答案,并重写了一个可以在/forum/.htaccess 文件中使用的版本,如果您决定将指令移到那里。
  • 非常内容丰富 - 谢谢。标记为已接受的答案。我之前谈过,没有forum 目录,只有forum-embed 安装到的位置。论坛只是 Wordpress 中的一个页面,您说得对,事实证明我需要重定向到静态文件。由于我在当前的实现中无法做到这一点,我将以另一种方式对其进行攻击。非常感谢所有的建议!
猜你喜欢
  • 2016-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-10
  • 2011-01-15
相关资源
最近更新 更多