我需要一些帮助来创建重定向,我正在尝试将所有内容替换为-
,+
但两者都是特殊字符,并且仅当 URL 包含 时才执行此操作?s=
。
这是一个例子
example.com/?s=i-need-to-rewrite-this-url
example.com/?s=i+need+to+rewrite+this+url
这就是我所拥有的,我已经尝试使用()
或""
但没有工作
RewriteEngine on
RewriteRule ^?s=(.*)\-(.*)$ ?s=$1\+$2 [L,R=301]
我很感激任何帮助。谢谢。
这些角色没有什么特别“特别”的地方。至少,不是在将要使用它们的上下文中。(
-
连字符) 在正则表达式字符类中使用时是范围说明符,否则它只是一个连字符,可以安全地在 URL 的查询字符串部分中使用未编码的内容(我们不需要在正则表达式字符类中使用它)。(+
plus) 是正则表达式量词,但我们不需要在正则表达式中使用它,只需在替换字符串中使用它(RewriteRule
指令的第二个参数,不是正则表达式)。是+
一个编码空间当在 URL 的查询字符串部分中使用时 - 我猜您已经意识到这一点,这就是为什么您需要重定向请求(尽管由于这是 URL 参数值的一部分,所以也很好奇为什么不能在应用程序)。然而,值得注意的一件事是,由于
+
是 URL 编码空间,我们确实需要在指令上使用NE
(noescape
) 标志RewriteRule
来防止 mod_rewrite在重定向响应中对+
as%2B
(文字)进行 URL 编码。(这同样适用于我们可能从- 此服务器变量未进行%解码的+
任何其他%编码字符。)QUERY_STRING
模式(第一个参数)仅与 URL 路径匹配,而不与查询字符串匹配
RewriteRule
。因此,RewriteRule
单独的指令永远不会匹配查询字符串。顺便说一句,?
是一个特殊的正则表达式字符(前面的标记的 0 或 1 个量词)并且^
(前面的标记)是不可量化的,所以我会惊讶这是否会编译(导致 500 内部服务器错误)。正则表达式中的文字?
需要进行反斜杠转义。如上所述,
NE
这里需要该标志。并且不需要在替换字符串+
中进行反斜杠转义,因为它在这里没有特殊含义(它不是正则表达式)。另外,由于相对替换字符串(即。),除非您定义了该字符串,否则这将导致格式错误的重定向。?s=$1\+$2
RewriteBase
要匹配查询字符串,您需要一个附加条件(
RewriteCond
指令)并匹配QUERY_STRING
服务器变量。因此,作为第一次尝试,您可以执行以下操作:请注意,
%1
和%2
反向引用(与 等相对)包含从前面的CondPattern(指令)$1
捕获的值,而不是模式(在本例中仅匹配空字符串)。RewriteCond
RewriteRule
(注意:您应该始终首先使用 302 - 临时 - 重定向进行测试,以避免潜在的缓存问题,并确保在测试之前清除所有中间缓存。)
我假设
s
是唯一的URL 参数。根据上述规则,后面的任何其他 URL 参数都将被丢弃。然而,上面的方法非常低效,因为它会为每个 实例触发外部重定向
-
。因此,您的示例/?s=i-need-to-rewrite-this-url
将触发 5 个重定向。解决方案
您应该在内部递归地替换除一个之外的所有内容,而不是上面的内容,
-
并且仅在替换所有内容后才触发外部重定向(并替换最后一个-
)-
。为此,我们需要额外重写来执行内部替换。例如:检查正则表达式的第一个条件
^s=([^&]*-[^&]*){2}
只是确定s
URL 参数的值中至少有 2 个连字符。(否则该规则将被跳过并直接进入第二个/重定向规则。)第二个条件然后捕获最后一个周围的查询字符串的相关部分-
,然后在下面的中使用它们RewriteRule
。该
N
标志使重写引擎立即重新启动。它20
设置了迭代次数的限制(Apache 2.4+) - 所以我假设不超过 20+1 个连字符(最后一个连字符在第二个/重定向规则中被替换)。由于我们知道处理第二条规则时 URL 参数中最多仅保留 1 个连字符,因此我将连字符添加到正则表达式字符类中作为优化,以避免不必要的回溯。
未来
replace
Apache 表达式中有一个函数,(顾名思义)允许您搜索/替换字符串中的字符,但我认为最新的公共版本中尚未提供该函数。但这可能允许您在单个规则中执行类似以下操作: