如何用Nginx替换下划线

时间:2013-04-09 20:47:33

标签: url-rewriting nginx

我有史以来第一次使用Nginx,基本上不了解它。

我需要在100+网址中将“_”替换为“ - ”。我认为必须有一个简单的方法来使用Nginx,但在Google上找不到任何东西。

谢谢!

编辑:

我的网址例如:http://www.mywebsite.com/this_category/page1.php

我需要这个:http://www.mywebsite.com/this-category/page1.php

2 个答案:

答案 0 :(得分:13)

不,没有 easy 方法可以做到这一点,但重写引擎仍然可以强制执行,假设您可以对需要转换的破折号数量设置合理的上限单个网址(或者即使您没有,请参阅答案的结尾。)

我是这样做的(测试代码):

rewrite ^([^_]*)_([^_]*)_([^_]*)_([^_]*)_([^_]*)_([^_]*)_([^_]*)_([^_]*)_(.*)$ $1-$2-$3-$4-$5-$6-$7-$8-$9;
rewrite ^([^_]*)_([^_]*)_([^_]*)_([^_]*)_(.*)$ $1-$2-$3-$4-$5;
rewrite ^([^_]*)_([^_]*)_(.*)$ $1-$2-$3;
rewrite ^([^_]*)_(.*)$ $1-$2;

这四个重写分别将url中的前8个,4个,2个和1个下划线转换为破折号。每条规则中的下划线数量有意减少2的幂。此块是最有效的规则集,它将在单个URL中从0到15次下划线转换,使用匹配或不匹配每个单独规则的所有16种组合。

您还会注意到,除了最后一个组之外,我在每个规则中都使用了[^_]*。这避免了在不匹配的情况下使正则表达式引擎执行不需要的回溯。基本上,在正则表达式中有九个通用星.*导致O(n 9 )复杂度(这是非常糟糕的)在“最坏情况”中,这是一个非匹配,实际上是你最常见的情况。 (对于那些希望真正理解底层库实际执行regexp的人,我可以推荐this book。)

出于这个原因,如果你可以对破折号的数量设置一个小于15的限制,我建议删除第一个规则,或者前两个规则。仅最后三条规则将最多转换为7个下划线;最后两个将最多转换为3。

最后,您没有提及将用户重定向到新网址。 (而不是仅仅在强调的网址和正确的网址上提供内容,这通常是搜索引擎坚果所不喜欢的。仅供参考。)如果这就是你所需要的,你将不得不将这些重写放入一个特殊的地方。在网址中存在下划线时触发的位置,并在四次重写结束时将用户重定向到新网址:

location ~ _ {
  rewrite ^([^_]*)_([^_]*)_([^_]*)_([^_]*)_([^_]*)_([^_]*)_([^_]*)_([^_]*)_(.*)$ $1-$2-$3-$4-$5-$6-$7-$8-$9;
  rewrite ^([^_]*)_([^_]*)_([^_]*)_([^_]*)_(.*)$ $1-$2-$3-$4-$5;
  rewrite ^([^_]*)_([^_]*)_(.*)$ $1-$2-$3;
  rewrite ^([^_]*)_(.*)$ $1-$2;
  rewrite ^ $uri permanent;
}

这还增加了在单个网址中翻译无限数量下划线的好处,但代价是更多的下划线重定向到用户的浏览器。

HTH ;-P

答案 1 :(得分:2)

这已经过时了,但我必须指明上面的答案需要更正为使用 n 不同数量的重新编号 n 是URL中存在的下划线数量是完全不必要的。使用3种不同的位置指令和重写规则可以解决这个问题,同时在常规表达中结合以下场景:

  1. 网址的END处有一个或多个下划线。
  2. 网址开头有一个或多个下划线
  3. 网址的MIDDLE中有一个或多个underocres

            location ~*^/(?<t1>\_+)(?<t2>[a-zA-Z0-9\-]*)$ { 
            return 301 $scheme://$host/-$t2; 
            }
    
            location ~*^/(?<t2>[a-zA-Z\_0-9\-]*)(?<t1>\_+)$ { 
            return 301 $scheme://$host/$t2-; 
            }
    
            location ~*^/(?<t2>[a-zA-Z0-9\-]*)(?<t1>\_+)(?<t3>[a-zA-Z0-9\-]*)$ { 
            return 301 $scheme://$host/$t2-$t3; 
            }
    
  4. 这三个指令会递归地用' - '替换所有下划线,直到没有留下

    -BeWilled