【问题标题】:Rewrite underscore to hyphen in existing set of mod_rewrite rules在现有的一组 mod_rewrite 规则中将下划线重写为连字符
【发布时间】:2016-03-14 16:16:23
【问题描述】:

我的 .htaccess 中有这组规则,我想添加其他规则(或更改现有规则),以便将 URL 中的所有下划线重写为连字符。

RewriteEngine on

#1--Redirect  "/?load=/foo" to "/foo"--#
RewriteCond %{THE_REQUEST} /\?load=/([^\s&]+) [NC]
RewriteRule ^ /%1? [NE,L,R]
#2--Rewrite "/foo" to "/?load=/foo--#
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)/?$ /?load=/$1 [NC,L,QSA]

另外,有没有办法限制连续连字符的数量?在某些 URL 上将 _ 重写为 - 会得到类似 file---data---backup 的结果,因为原始 URL 在两个下划线之间有一个连字符。我可以以某种方式将此类 URL 转换为例如改为file-data-backup

【问题讨论】:

    标签: apache .htaccess mod-rewrite


    【解决方案1】:

    您可以使用额外的重定向规则:

    RewriteEngine on
    
    #1 Redirect rule to convert _ to -
    RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+(.*?)_+[_-]*(.+?)\sHTTP [NC]
    RewriteRule ^ /%1-%2 [L,NE,R=302]
    
    #2--Redirect  "/?load=/foo" to "/foo"--#
    RewriteCond %{THE_REQUEST} /\?load=/([^\s&]+) [NC]
    RewriteRule ^ /%1? [NE,L,R=302]
    
    #3--Rewrite "/foo" to "/?load=/foo--#
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.+)/?$ /?load=/$1 [L,QSA]
    

    【讨论】:

    • 太棒了,就像一个魅力。还有一个问题:有没有办法限制连字符的数量?由于它在某些 url 上将 _ 重写为 - 我得到“文件---数据---备份”表单,因为下划线之间有一个连字符。我能以某种方式获得“文件数据备份”表格吗?
    • 这取决于页面/文章名称。管理员插入带有空格和连字符的名称。例如“税费 - 2016”。网址为 tax_fees_-_2016。根据您的规则,它的税费---2016 年。如果可能的话,我想以某种方式动态删除不必要的炒作。
    • 这可能有效,但它不必要地复杂且效率低下。描述的方法例如在this answer 中更可取。
    • @anubhava:正如给定的那样,它不涉及查询字符串。我不相信 OP 也不需要这样做,因为他们现有规则所暗示的 URL 方案(像 /foo-bar-baz 这样的外部可见 URL,在内部转换为 /?load=foo-bar-baz)。
    • 在没有相关信息或提供示例 URL 的情况下,我不能假设查询字符串应该保持不变。其次,链接的答案将/tax_fees_-_2016 转换为/tax-fees---2016,但OP 想要/tax-fees-2016
    【解决方案2】:

    描述的方法,例如this answer 中的内容应该适合您,只需稍作调整。主要是,您需要添加一些 RewriteConds 以防止它应用于与图像和其他实际文件对应的任何 URL:

    # Replace all but the last underscore with dashes internally:
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^([^_]*)_([^_]*_.*)$ $1-$2 [N]
    
    # Replace the last underscore and issue a HTTP permanent redirect:
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^([^_]*)_([^_]*)$ /$1-$2 [L,R=301]
    

    (在现有规则之前添加这些规则,但在 RewriteEngine On 行之后。请注意,如果您知道自己没有并且不会有任何名称中带有下划线的实际文件,则可以省略 RewriteConds。)

    您还可以修改这些规则以折叠连续的连字符:

    # Collapse all but one group of multiple hyphens internally:
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^([^-]*(-[^-]+)*)--+([^-]+(-[^-]+)*--.*)$ $1-$3 [N]
    
    # Collapse the last group of hyphens and issue a HTTP permanent redirect:
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^([^-]*(-[^-]+)*)--+([^-]+(-[^-]+)*|)$ /$1-$3 [L,R=301]
    

    甚至同时进行:

    # Collapse all but one group of multiple hyphens and/or underscores internally:
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^([^-_]*(-[^-_]+)*)(--|-_|_)[-_]*([^-_]+(-[^-_]+)*(--|_).*)$ $1-$4 [N]
    
    # Collapse the last group of hyphens and/or underscores and issue a HTTP permanent redirect:
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^([^-_]*(-[^-_]+)*)(--|-_|_)[-_]*([^-_]+(-[^-_]+)*|)$ /$1-$4 [L,R=301]
    

    (免责声明:我没有实际测试过这些规则。我相信它们应该可以工作,但我可能在某个地方打错了。)

    这些规则都不会以任何方式影响查询字符串,这可能是您想要的。如果您确实也想替换查询字符串中的下划线和/或多个连续连字符,您可以这样做,例如使用on the Apache httpd wiki here描述的方法。

    【讨论】:

      猜你喜欢
      • 2014-06-05
      • 1970-01-01
      • 1970-01-01
      • 2012-07-22
      • 2010-12-25
      • 1970-01-01
      • 1970-01-01
      • 2013-09-05
      • 2017-04-06
      相关资源
      最近更新 更多