
本文讲解如何使用 javascript 的 `sort()` 方法,结合正则提取与数值比较,对包含递增数字后缀的文件名数组进行正确升序排序,解决默认字符串排序导致的 `13810` 错排在 `1386` 之前的常见问题。
JavaScript 中原生的 Array.prototype.sort() 默认按字符串 Unicode 码点排序,而非数值大小。因此,当文件名如 "IMG_COM_..._13810.webp" 与 "IMG_COM_..._1386.webp" 混合时,字符串比较会先比 '1381'
要实现按末尾数字部分的数值大小升序排列(即自然排序),需提供自定义比较函数,并准确提取该数字。观察示例数据:
const img = [ "IMG_COM_20220516_1150_41_1375.webp", "IMG_COM_20220516_1150_41_13810.webp", "IMG_COM_20220516_1150_41_1386.webp", // ... ];
所有文件名均以 _ 分隔,数字位于倒数第一段(_.webp 前),因此可采用两种稳健提取方式:
✅ 推荐:正则提取(更健壮)
使用 /\d+(?=\.\w+$)/ 匹配最后一个点号前的连续数字:
img.sort((a, b) => {
const numA = parseInt(a.match(/\d+(?=\.\w+$)/)[0], 10);
const numB = parseInt(b.match(/\d+(?=\.\w+$)/)[0], 10);
return numA - numB; // 升序;若需降序,改为 `numB - numA`
});✅ 备选:字符串分割(适用于固定格式)
如确认数字总在最后一段下划线后、扩展名前,也可用:
img.sort((a, b) => {
const numA = parseInt(a.split('_').slice(-1)[0].split('.')[0], 10);
const numB = parseInt(b.split('_').slice(-1)[0].split('.')[0], 10);
return numA - numB;
});⚠️ 注意事项: 必须使用 parseInt(..., 10) 明确指定十进制,避免八进制解析风险; 正则方案对文件名格式变化(如多级子目录、不同分隔符)更具鲁棒性; 若存在无法匹配数字的项,建议增加空值防护:?.[0] || '0'; sort() 是原地排序,会直接修改原数组;如需保留原始顺序,请先 .slice() 或 [...arr] 浅拷贝。
执行后,输出完全符合预期:
[ "IMG_COM_20220516_1150_41_1375.webp", "IMG_COM_20220516_1150_41_1386.webp", "IMG_COM_20220516_1150_41_1389.webp", "IMG_COM_20220516_1150_41_13810.webp", "IMG_COM_20220516_1150_41_13911.webp", "IMG_COM_20220516_1150_41_13912.webp" ]
掌握这种“提取—转换—比较”模式,即可灵活应对各类基于内嵌数值的字符串排序需求。










