正则表达式需求:去重音特殊字符,保留连字符、下划线及扩展名
解决文件名去重音、保留合法字符及扩展名的问题
要实现去除文件名重音、保留-/_和文件扩展名的需求,可以分两步处理,避免误删扩展名的最后一个点:
处理步骤
- 移除重音符号:利用
String.prototype.normalize('NFD')将带重音的字符分解为基础字符+重音标记,再移除所有重音标记(对应Unicode范围\u0300-\u036f)。 - 清理非法字符并保留扩展名:将文件名拆分为主体部分和扩展名,仅清理主体中的非法字符(保留字母、数字、
-、_),最后拼接回扩展名。
代码实现
方案一:拆分文件名处理(直观不易出错)
function cleanFilename(filename) { // 第一步:去除重音符号 const withoutAccents = filename.normalize('NFD').replace(/[\u0300-\u036f]/g, ''); // 第二步:拆分文件名主体与扩展名 const parts = withoutAccents.split('.'); if (parts.length === 1) { // 无扩展名,直接清理所有非法字符 return parts[0].replace(/[^a-zA-Z0-9-_]/g, ''); } const extension = parts.pop(); const mainName = parts.join('').replace(/[^a-zA-Z0-9-_]/g, ''); return `${mainName}.${extension}`; } // 测试示例1 const test1 = "ÁÉÍÓÚáéíóúâêîôûàèìòùÇãç.,~!@#$%&_-12345.png"; console.log(cleanFilename(test1)); // 输出:AEIOUaeiouaeiouaeiouCac_-12345.png // 测试示例2 const test2 = "ÁÉÍÓÚáéíóúâêîôûàèìòùÇãç.,~!@#$%&-12.34.5.png"; console.log(cleanFilename(test2)); // 输出:AEIOUaeiouaeiouaeiouCac-12345.png
方案二:正则一次性处理(简洁写法)
function cleanFilename(filename) { return filename .normalize('NFD') .replace(/[\u0300-\u036f]/g, '') // 移除重音 .replace(/(?!\.[^.]*$)[^a-zA-Z0-9-_]/g, ''); // 匹配所有非合法字符,排除最后一个点及其后的扩展名部分 } // 测试结果与方案一一致
原代码问题说明
- 你最初的正则
/\[^a-zA-Z0-9-_\]/g多了一个不必要的转义符\,导致正则逻辑错误;同时该正则会移除所有点号,无法保留扩展名的最后一个点。 - 尝试的负向回溯正则逻辑有误,无法正确识别并移除除最后一个点外的其他非法字符,因此处理含多点点的文件名时效果不符合预期。
内容的提问来源于stack exchange,提问作者allan.egidio
相关产品推荐
相关产品推荐

