Apache RewriteRule 默认不匹配问号后的查询字符串,因其仅处理路径部分,查询字符串被剥离并存于%{QUERY_STRING}变量中;必须用RewriteCond单独捕获,再通过%1等引用,结尾加?可清除原始参数。

Apache 的 RewriteRule 默认**不匹配问号后的查询字符串(query string)**,比如 ?cid=101000 这部分。要重写带参数的 URL,必须用 RewriteCond %{QUERY_STRING} 单独捕获参数,再在 RewriteRule 中引用。
为什么不能直接在 RewriteRule 里写问号?
因为 Apache 的重写引擎只对路径(path)部分做模式匹配,? 及其后面的内容属于查询字符串,被剥离后单独存放在 %{QUERY_STRING} 变量中。直接在规则里写 ^/index.php?cid=(\d+) 是无效的。
使用ydata-profiling(前身为pandas-profiling)生成全面的数据质量报告,包含相关性分析、缺失值模式和基数检测。导出交互式HTML仪表板和JSON摘要。
正确写法:用 RewriteCond 捕获 QUERY_STRING
例如把 /index.php/index/supply.html?cid=101000 重定向为 /sell/list-101000.html:
- 先用
RewriteCond %{QUERY_STRING} ^cid=(.+)$提取参数值,保存到%1 - 再用
RewriteRule ^/index\.php/index/supply\.html$ /sell/list-%1.html? [R=301,L] - 结尾的
?很关键——它会清空原始查询字符串,避免新 URL 带上?cid=101000 -
%1引用的是RewriteCond中括号捕获的内容;$1才用于RewriteRule路径本身的捕获
常见组合场景示例
• 强制跳转并保留部分参数:RewriteCond %{QUERY_STRING} ^id=(\d+)&type=(\w+)RewriteRule ^/old\.php$ /new/%1-%2? [R=301,L]
→ 把 /old.php?id=123&type=article 变成 /new/123-article
• 匹配任意参数并统一转发:RewriteCond %{QUERY_STRING} .+RewriteRule ^/product\.php$ /product? [L]
→ 清除所有参数,内部转发到干净路径
调试小贴士
- 开启 Apache 重写日志(
RewriteLogLevel 8+RewriteLog)可看到每步匹配过程 - 用在线工具如 htaccess tester 验证规则逻辑
- 注意
OR标志配合多个RewriteCond时的优先级,避免误匹配

















