您绝对应该在 PHP 中执行此操作。这是一个可行的解决方案,但需要为 URL 中的每个破折号通过 RewriteRule,所以我不推荐它。但不管:
RewriteEngine On
RewriteRule ^(.*)-(.*)$ $1_$2 [QSA]
为了澄清这里会发生什么,如果请求是 for http://www.example.com/argument-1/argument-2/argument-3,RewriteRule则将运行多次,因为它每次只能替换一个破折号。所以 URL 将被转换成这样:
通过 1:http://www.example.com/argument-1/argument-2/argument_3
通过 2:http://www.example.com/argument-1/argument_2/argument_3
通过 3:http://www.example.com/argument_1/argument_2/argument_3
至于$1and $2,它们指的是正则表达式中带括号的组件。正则表达式 ,^(.*)-(.*)$分解如下:
^- 匹配 URI 的开头
(.*)- 匹配(并捕获)任意数量的字符,这将$1在替换中
-- 匹配破折号
(.*)- 匹配(并捕获)任意数量的字符,这将$2在替换中
$- 匹配 URI 的结尾
所以第一次通过, $1will be/argument-1/argument-2/argument和$2will be 3。然后替换在它们两个之间放置一个下划线并创建一个新的 URI:
/argument-1/argument-2/argument_3
然后它再次运行,因为正则表达式仍然匹配新的 URI(因为它有 a -)并且$1is/argument-1/argument和$2is 2/argument_3。然后替换在它们两个之间放置一个下划线并创建一个新的 URI:
/argument-1/argument_2/argument_3
然后它再次运行,因为正则表达式仍然匹配新的 URI(因为它有 a -)并且$1is/argument和$2is 1/argument_2/argument_3。然后替换在它们两个之间放置一个下划线并创建一个新的 URI:
/argument_1/argument_2/argument_3
然后 Apache 继续使用这个 URI,因为正则表达式不再匹配(因为没有更多的破折号)。