1

我为客户开发了一个新网站来替换现有网站。他们以前的网站有一些看起来很讨厌的产品 URL。例如,旧网址:

http://mydomain.com/p/-3-0-Some-Ugly-Product-Info-With-1-3pt-/a-arbitrary-folder/-18pt/-1-8pt-/ABC1234

我想捕获对使用这些旧 URL 的新站点的所有请求。我需要的旧 URL 信息是ABC1234产品 ID。澄清一下,旧 URL 以/p/四级文件夹开头,然后是产品 ID。

因此,例如,上面的 URL 需要重写为:

http://mydomain.com/shop/?sku=ABC1234

我在 Linux 上使用 Apache 2.2。谁能指出我要匹配的正确模式?我知道这是错误的,但这是我目前所处的位置:

RewriteRule ^p/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)?$ shop/?sku=$5 [R=301,NC,L]

我很确定用于匹配 4 个文件夹中的每一个的模式是多余的,但我对正则表达式并不那么敏锐。我尝试了一些在线正则表达式评估器,但没有成功。

谢谢你。

--编辑#1--

实际上,我上面的 RewriteRule 确实有效,但有没有办法缩短它?

--编辑#2--

感谢 ddr,我已经能够将此表达式归结为:

RewriteRule ^p/([\w-]+/){4}([\w-]+)$ shop/?_sku=$2 [R=301,NC,L]

--编辑#3--

主要是为了 ddr 的利益,但我欢迎任何可以提供帮助的人。我正在处理超过 10,000 个需要重写才能使用新站点的 URL。到目前为止我提供的信息仍然有效,但现在我正在测试所有旧 URL 是否都被正确重写,我遇到了一些不适用于 ddr 提供的 RewriteRule 示例的异常情况。

旧的 URL 是一致的,因为我需要的产品 ID 位于 URL 的最后,如上所述。第一个文件夹始终是/p/. 我现在遇到的问题是一些 URL 有一个 URL 编码的双引号 (")。此外,一些 URL 包含一个 /-/ 作为提到的四个文件夹之一。所以这里有一些示例旧网址的变化:

/p/-letters-numbers-hyphens-88/another-folder/-and-another-/another-18/ABC1234

/p/-letters-numbers-hyphens-88/2%22/-/-/ABCD1234

/p/letters-numbers-hyphens-1234/34-88/-22/-/ABCD1234/

尽管旧的 URL 很讨厌,但我认为可以肯定地说以下内容总是正确的:

  • 每个都以 /p/ 开头
  • 每个都以我需要隔离的产品 ID 结尾。
  • /p/ 和产品 ID 之间总是有四级文件夹。
  • 中间的一些文件夹有连字符,有的没有。
  • 中间的一些文件夹仅是连字符。
  • 中间的一些文件夹包含一个 % 字符,它们是 URL 编码的。
  • 有些请求/在最后包含 a ,有些则不包含。

以下规则由 ddr 提供并且运行良好,直到我遇到包含 % 百分号或只有连字符的文件夹的 URL:

RewriteRule ^p/(?:[\w-]+/){4}([\w-]+)$ shop/?_sku=$1 [R=301,NC,L]

鉴于上述规则,我如何编辑它以允许仅包含连字符 (/-/) 或百分号的文件夹?

4

1 回答 1

2

您可以使用字符类来减少一些长度。正如@jpmc26 所说,括号(捕获组)也是不必要的,除了最后一个。

我对 Apache 规则不是特别熟悉,但试试这个:

RewriteRule ^p/(?:[\w-]+/){4}([\w-]+)$ shop/?sku=$1 [R=301,NC,L]

如果支持扩展正则表达式,它应该可以工作。

  • \w等效于[A-Za-z0-9_]并且您不需要捕获下划线,因此这是一种替代方法。
  • 恰好匹配前一组的{4}四次重复。这并不总是受支持,因此 Apache 可能不喜欢它。
  • ?:是可选的,但表示不应将这些括号视为捕获。让它稍微更有效率。

我不确定最后 [] 中的部分是什么,但我离开了它。我不明白为什么你需要在?之前$,所以我把它拿出来了。

编辑:如果 Apache 喜欢,最紧凑的方式可能是

RewriteRule ^p(/[\w-]+){5}$ shop/?sku=$5 [R=301,NC,L]

编辑:对问题编辑 3 的回复。

我很惊讶它不适用于 only -[\w-]+即使只有一个 . 也应该匹配-。您确定这些 URL 中没有其他内容吗?

您也可以尝试-在正则表达式中替换为\-.

至于,就%改成。确保你在最后离开!否则,正则表达式引擎将尝试将其解释为 char 序列的一部分。[\w-][\w%-]-

编辑2:或者试试这个: RewriteRule ^p/(?:.*?/){4}(.*?)/?$ shop/?sku=$1 [R=301,NC,L]

于 2013-07-12T05:52:43.017 回答