我开发了一个新网站来替换客户端的现有网站。他们以前的网站有一些非常讨厌的URL到他们的产品。例如,旧网址:
http://mydomain.com/p/-3-0-Some-Ugly-Product-Info-With-1-3pt-/a-arbitrary-folder/-18pt/-1-8pt-/ABC1234
我想抓住所有使用这些旧网址的新网站的请求。我需要的旧网址信息是ABC1234
,它是产品ID。为了澄清,旧网址以/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/
虽然旧的网址很糟糕,但我认为可以说以下内容始终是正确的:
/
,有些则不包括。以下规则由ddr提供并且运行良好,直到我遇到包含%百分号的网址或仅包含连字符的文件夹:
RewriteRule ^p/(?:[\w-]+/){4}([\w-]+)$ shop/?_sku=$1 [R=301,NC,L]
根据上述规则,如何编辑它以允许仅限连字符(/ - /)或百分号的文件夹?
答案 0 :(得分:2)
您可以使用字符类来减少一些长度。除了最后一个,括号(捕获组)也是不必要的,正如@jpmc26所说。
我对Apache规则并不是特别熟悉,但试试这个:
RewriteRule ^p/(?:[\w-]+/){4}([\w-]+)$ shop/?sku=$1 [R=301,NC,L]
如果支持扩展正则表达式,它应该有效。
\w
相当于[A-Za-z0-9_]
,您不需要不捕获下划线,因此这是一个替代品。 {4}
恰好匹配前一组的四次重复。这并不总是支持,因此Apache可能不喜欢它。 ?:
是可选的,但表示不应将这些parens视为捕获。使它更有效率。 我不确定[]最后的部分是什么,但是我离开了。我无法理解为什么在?
之前需要$
,所以我把它拿出来了。
编辑:如果Apache喜欢它,最紧凑的方式可能是
RewriteRule ^p(/[\w-]+){5}$ shop/?sku=$5 [R=301,NC,L]
编辑:回复编辑问题3。
我很惊讶它只适用于-
。即使只有一个[\w-]+
,-
也应匹配。您确定这些网址中没有其他内容吗?
您也可以尝试使用-
替换正则表达式中的\-
。
至于%
,只需将[\w-]
更改为[\w%-]
即可。确保最后留下-
!否则,正则表达式引擎将尝试将其解释为char序列的一部分。
编辑2:或试试这个:
RewriteRule ^p/(?:.*?/){4}(.*?)/?$ shop/?sku=$1 [R=301,NC,L]