应使用 /.[^/\?#]+$/ 匹配任意长度文件扩展名,它从最后一个点匹配至行尾非路径/url特殊字符,结合 basename() 提取纯文件名并排除隐藏文件,确保准确捕获 .tar.gz、.min.js 等复合扩展名。

要匹配任意长度的文件扩展名,比如 .jpg、.tar.gz、.min.js 或 .php5.6,不能只写 .w+——它会漏掉带连字符、数字开头或含点号的合法扩展名,也无法区分末尾的点是否属于扩展名而非文件名的一部分。
基础场景:匹配标准单段扩展名(如 .txt、.log)
第一步:用锚定确保匹配的是文件名末尾的扩展名。
写正则 /.[a-zA-Z0-9]+$/,其中 $ 保证点号后的内容紧贴字符串结尾。
第二步:允许下划线和短横线,覆盖 .my_config 或 .css-v2 这类常见命名。
改写为 /.[a-zA-Z0-9_-]+$/。注意这里 - 放在字符组末尾,避免被误解析为范围符。
第三步:测试时发现 report.tar.gz 只匹配到 .gz,但你实际需要完整扩展名 .tar.gz——这时候单段正则已不适用,必须切换策略。
进阶需求:匹配多段/复合扩展名(如 .tar.gz、.min.js)
方法一:用非贪婪回溯匹配从最后一个点开始到结尾的所有内容
正则:/.[^/?#]+$/。它从最后一个点出发,吃掉后面所有非路径分隔符、非URL特殊字符,直到行尾。这能捕获 .tar.gz、.dist.zip.enc 等任意长度组合。
方法二:显式限定“点+字母数字+可选的点+字母数字”重复结构
正则:/.(?:[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*.)*[a-zA-Z0-9]+$/。这个模式强制每一段都以字母数字开头结尾,中间可用短横线,段之间用点连接。它能匹配 .php、.es6.js、.foo-bar.baz,但拒绝 .123abc(数字开头)或 .-test(短横开头)。
【关键前提】该正则依赖 mb_ereg 或 PCRE 的 Unicode 模式才能正确处理中文路径;若未启用 u 修饰符,遇到 UTF-8 文件名如 文档.pdf 会截断乱码。
安全提取:排除误匹配路径中的点(如 /home/user/.config)
第一步:先用 basename() 提取纯文件名,剥离路径干扰$filename = basename($path);
第二步:检查文件名中是否至少含一个点,且点不在开头位置
如果 $filename[0] === '.',说明是隐藏文件(如 .gitignore),此时整个文件名就是名字,没有扩展名——直接返回空。
第三步:执行最终匹配
用 preg_match('/.[^/\?#]+$/', $filename, $matches)。这个正则不加 ^ 锚定开头,只关心末尾结构,配合 basename 已过滤路径,结果可靠。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











