You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用R语言正则表达式实现文件路径的多级数字排序?

文件路径的层级化自然排序问题

我有数百个.wav文件,通过list.files()函数导入后得到如下文件路径列表:

[1] "10/Project_English-10/BL-0001_A-conifer-cone-contains-seeds/Balsam-poplar-English-0701.wav"           
[2] "10/Project_English-10/BL-0001_A-conifer-cone-contains-seeds/Birch-English-0700.wav"                    
[3] "10/Project_English-10/BL-0001_A-conifer-cone-contains-seeds/Blueberry-English-0703.wav"  
.......
[73] "3/Project_English-3/BL-0002_Lesser-horseshoe-bat/Capercaillie-English-0069.wav"                        
[74] "3/Project_English-3/BL-0002_Lesser-horseshoe-bat/Fat-tail-scorpion-English-0082.wav"                   
[75] "3/Project_English-3/BL-0002_Lesser-horseshoe-bat/Fire-salamander-English-0067.wav"                     

我尝试用以下代码排序:

filename <- file_list[order(as.numeric(stringr::str_extract(file_list,"[0-9]+(.*?)")) )]

但这段代码只能让路径首个数字按数值排序(比如3开头的路径排在10开头之前),无法让最后一个子路径中的数字(如English-0067、English-0069)也按数值顺序排列。单独匹配最后一个子路径的数字排序又会打乱已有的路径层级顺序,请问如何实现所有子路径中的数字均按数值顺序排序?


解决方案:实现层级化自然排序

方法1:使用第三方包快速解决

R的gtools包提供了mixedsort()函数,能自动识别路径中每个分段的数字,按数值大小排序,同时保留路径层级顺序:

  1. 安装并加载包:
install.packages("gtools")
library(gtools)
  1. 执行排序:
filename <- mixedsort(file_list)

这个函数会先按最上层目录的数字(3 < 10)排序,同一目录下按子目录的数字(BL-0001 < BL-0002),最后按文件名里的数字(English-0067 < English-0069 < English-0082),完全满足需求。

方法2:自定义函数实现无依赖排序

如果不想依赖第三方包,可以自己生成多层排序键:

# 生成自然排序的分段键
natural_sort_key <- function(x) {
  # 拆分字符串为文本和数字交替片段
  parts <- strsplit(x, "(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)", perl = TRUE)[[1]]
  # 将数字片段转为数值,文本片段保留原样
  sapply(parts, function(p) {
    if(grepl("^\\d+$", p)) as.numeric(p) else p
  })
}

# 生成排序键矩阵,按层级排序
sort_keys <- do.call(rbind, lapply(file_list, natural_sort_key))
filename <- file_list[do.call(order, as.data.frame(sort_keys))]

这段代码会把每个路径拆分成文本和数字片段,将这些片段作为多层排序依据,实现和mixedsort()一致的效果。

内容的提问来源于stack exchange,提问作者Pengcheng Lai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 04:10:13