ci路由正则匹配中文失败的根本原因是uri编码与正则编码不一致:浏览器发送的中文url被百分号编码(如%e4%bd%a0),而[\u4e00-\u9fff]需匹配utf-8解码后的汉字,但ci3不支持u修饰符、ci4必须显式添加且依赖全程utf-8链路。

CI 的路由正则匹配中文失败,根本原因不是正则写错了,而是 $_SERVER['REQUEST_URI'] 或框架内部 URI 解析环节的编码与你写的正则不一致——多数情况下,URI 已被转义为 UTF-8 百分号编码(如 %E4%BD%A0%E5%A5%BD),而你直接拿未解码的原始字符串去匹配 [\u4e00-\u9fff],必然失败。
为什么 [\u4e00-\u9fff] 在路由里永远不生效
CodeIgniter(尤其是 CI3)在解析 URI 时,会先对 $_SERVER['REQUEST_URI'] 做 urldecode() 处理,但这个过程依赖服务器环境和 PHP 版本;CI4 则统一走 URI 类解析,默认按 UTF-8 解码。问题在于:你写的正则表达式是运行在「已解码后的 URI 字符串」上,但如果你没确认这个字符串确实是 UTF-8 编码的汉字(而非 GBK 字节流或乱码),[\u4e00-\u9fff] 就无法命中。
- Windows + IE/Edge 下上传或跳转带中文的 URL,
$_SERVER['REQUEST_URI']可能是 GBK 编码字节,urldecode()后变成乱码,正则自然不匹配 - CI3 的
$route数组规则不支持 Unicode 标志(u修饰符),即使写/^[\u4e00-\u9fff]+$/u,PHP 也会报错或静默忽略 - CI4 的
$routes->add()支持正则,但必须显式加'u'修饰符,否则 \uXXXX 不识别
$routes->add() 中正确匹配中文的写法(CI4)
CI4 允许在 $routes->add() 第二个参数传正则字符串,但需满足两个硬性条件:字符串用 'u' 修饰符、输入 URI 确实是 UTF-8。
当代理已经知道网站路由或内容URL,并且在启动前需要有效的sitemap XML、sitemap索引或robots.txt引用时,请使用sitemap。这是一个发布构件技能,而不是爬虫或SEO平台。
- 正确示例:
$routes->add('article/([\u4e00-\u9fff\-]+)', 'Article::view/$1');—— 缺少u修饰符会完全失效 - 更稳妥写法(显式声明):
$routes->add('article/([\x{4e00}-\x{9fff}]+)', 'Article::view/$1', ['constraints' => ['any' => 'u']]);,但注意 CI4 并不原生支持constraints这种写法,实际应改用$routes->setPlaceholder()配合自定义占位符 - 推荐替代方案:用
$routes->addPlaceholder('chinese', '[\x{4e00}-\x{9fff}]+'); $routes->get('post/(:chinese)', 'Post::show');,这是 CI4 官方支持且可读性更强的方式
CI3 中绕过正则、安全支持中文路由的实践
CI3 的 $route 不支持 Unicode 正则,硬写 /[\u4e00-\u9fff]/ 会直接导致解析失败或 500 错误。此时应放弃在路由层做中文匹配,改用「语义化路径 + 后端解码」组合。
- 前端把中文转成拼音或 slug(如
/article/wo-shi-zhong-guo-ren),路由用:any或[a-z0-9\-]+匹配,控制器里再urldecode()或查表还原 - 若必须用中文路径(如 SEO 强需求),在
application/config/routes.php顶部加:$_SERVER['REQUEST_URI'] = mb_convert_encoding($_SERVER['REQUEST_URI'], 'UTF-8', 'auto');,再写$route['article/([^/]+)'] = 'blog/show/$1';,靠后端mb_convert_encoding($this->uri->segment(2), 'UTF-8', 'auto')统一转码 - 绝对不要修改
system/core/URI.php去强行支持中文正则——升级时会被覆盖,且破坏框架稳定性
真正棘手的不是“怎么写正则”,而是确认从浏览器发请求 → Apache/Nginx 接收 → PHP $_SERVER → CI 路由解析,这一整条链路中每个环节的编码是否始终为 UTF-8。漏掉任一环,[\u4e00-\u9fff] 就只是摆设。










