Url rewriting 如何用Nginx替换下划线到破折号

Url rewriting 如何用Nginx替换下划线到破折号,url-rewriting,nginx,Url Rewriting,Nginx,我第一次使用Nginx,但基本上对它一无所知 我需要在100+URL中用“-”替换“\u1”。我想用Nginx一定有一个简单的方法,但是在谷歌上找不到任何东西 谢谢 编辑: 例如,我的url是: 我需要这样做:不,这不是一个简单的方法,但是重写引擎仍然可以强制执行,假设您可以在单个url中对需要转换的破折号数量设置合理的上限(或者即使您没有,请参见答案的结尾) 下面是我的做法(测试代码): 这四次重写分别将url中的前8、4、2和1下划线转换为破折号。每个规则中的下划线数都是故意减少2的幂。此块

我第一次使用Nginx,但基本上对它一无所知

我需要在100+URL中用“-”替换“\u1”。我想用Nginx一定有一个简单的方法,但是在谷歌上找不到任何东西

谢谢

编辑:

例如,我的url是:

我需要这样做:

不,这不是一个简单的方法,但是重写引擎仍然可以强制执行,假设您可以在单个url中对需要转换的破折号数量设置合理的上限(或者即使您没有,请参见答案的结尾)

下面是我的做法(测试代码):

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

您还将注意到,我在每个规则中都对每个组使用了
[^\uz]*
,但最后一个组除外。这避免了在不匹配的情况下让regexp引擎执行不必要的回溯。基本上,在一个regexp中有九个通用星
*
,在“最坏情况”中会导致O(n9)复杂性(这是非常糟糕的),这是一个不匹配的情况,实际上是最常见的情况。(我可以向那些希望真正了解底层库如何实际执行regexp的人推荐。)

因此,如果可以将破折号的数量限制小于15,我建议删除第一条规则或前两条规则。仅最后三条规则就可以翻译成7个下划线;最后两个将转换为3

最后,您没有提到将用户重定向到新的url。(与只在带下划线的url和正确的url上提供内容不同,搜索引擎的狂热者通常不赞成这样做。仅供参考。)如果这是您需要的,您必须将这些重写放到一个特殊位置,该位置在url中出现下划线时触发,这会在四次重写结束时将用户重定向到新url:

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;
}
这也增加了在一个url中传输不限数量的下划线的好处,而牺牲了多个重定向到用户浏览器的代价

HTH-P

不,这不是一个简单的方法,但是重写引擎仍然可以强制执行,前提是您可以在单个url中对需要转换的破折号数量设置合理的上限(或者即使您没有,请参见答案的结尾)

下面是我的做法(测试代码):

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

您还将注意到,我在每个规则中都对每个组使用了
[^\uz]*
,但最后一个组除外。这避免了在不匹配的情况下让regexp引擎执行不必要的回溯。基本上,在一个regexp中有九个通用星
*
,在“最坏情况”中会导致O(n9)复杂性(这是非常糟糕的),这是一个不匹配的情况,实际上是最常见的情况。(我可以向那些希望真正了解底层库如何实际执行regexp的人推荐。)

因此,如果可以将破折号的数量限制小于15,我建议删除第一条规则或前两条规则。仅最后三条规则就可以翻译成7个下划线;最后两个将转换为3

最后,您没有提到将用户重定向到新的url。(与只在带下划线的url和正确的url上提供内容不同,搜索引擎的狂热者通常不赞成这样做。仅供参考。)如果这是您需要的,您必须将这些重写放到一个特殊位置,该位置在url中出现下划线时触发,这会在四次重写结束时将用户重定向到新url:

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;
}
这也增加了在一个url中传输不限数量的下划线的好处,而牺牲了多个重定向到用户浏览器的代价


HTH-P

这已经过了规定的时间,但我必须指出,上面的答案需要更正,因为使用不同数量的重新布线,其中n是URL中存在的下划线数量,这是完全不必要的。使用3个不同的位置指令和重写规则可以解决此问题,同时在其常规表达式中协调以下场景:

  • url末尾有一个或多个下划线
  • url开头有一个或多个下划线
  • url中间有一个或多个底字符

            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; 
            }
    
    location~*^/(?\\\+([a-zA-Z0-9\-]*)${
    返回301$scheme://$host/-$t2;
    }
    位置~*^/(?[a-zA-Z\\\u 0-9\-]*)(?\\\+)${
    返回301$scheme://$host/$t2-;
    }
    位置~*^/(?[a-zA-Z0-9\-]*)(?\\+([a-zA-Z0-9\-]*)${
    返回301$scheme://$host/$t2-$t3;
    }
    
  • 这三条指令将递归地将所有下划线替换为“-”,直到没有下划线为止


    -困惑

    这已经过了到期时间,但我必须指出,上面的答案需要更正,因为使用不同数量的重新布线,其中n是URL中存在的下划线数量,这是完全不必要的。这个问题可以通过使用3个不同的位置指令和重写ru来解决
    # Replace maximum of 3 or 1 underscores per internal redirect,
    # produce 500 Internal Server Error after 10 internal redirects, 
    # supporting at least 28 underscores (9*3 + 1*1) and at most 30 (10*3).
    location ~ _ {
        rewrite "^([^_]*)_([^_]*)_([^_]*)_(.*)$" $1-$2-$3-$4 last;
        rewrite "^([^_]*)_(.+)$" $1-$2 last;
        return 301 $uri;
    }