在R中获取不带扩展名的文件名

Get filename without extension in R

我有一个文件:

ABCD.csv 

.csv之前的长度不固定,可以任意变化。

如何提取.csv之前的部分?

您可以使用 subsubstr

sub('\.csv$', '', str1) 
#[1] "ABCD"

substr(str1, 1, nchar(str1)-4)
#[1] "ABCD"

使用来自@JasonV 的 post

的 'file_path'
sub('\..*$', '', basename(filepath))
#[1] "ABCD"

library(stringr)
str_extract(filepath,  perl('(?<=[/])([^/]+)(?=\.[^.]+)'))
#[1] "ABCD"

数据

str1 <- 'ABCD.csv'

标准安装 tools 包中有一个内置的 file_path_sans_ext 包可以抓取没有扩展名的文件。

tools::file_path_sans_ext("ABCD.csv")
## [1] "ABCD"

basename 也将删除通向文件的路径。使用此正则表达式,任何扩展名都将被删除。

filepath <- "d:/Some Dir/ABCD.csv"
sub(pattern = "(.*)\..*$", replacement = "\1", basename(filepath))

# [1] "ABCD"

或者,按照 Tyler Rinker 的建议使用 file_path_sans_ext

file_path_sans_ext(basename(filepath))

# [1] "ABCD"

你也可以试试这个:

data <- "ABCD.csv"
gsub(pattern = "\.csv$", "", data)

#[1] "ABCD"

这对于文件列表也很有用,比如说

data <- list.files(pattern="\.csv$") ,使用代码将删除列表中所有文件的扩展名。

这是一个适用于压缩和多个文件的实现:

remove.file_ext <- function(path, basename = FALSE) {
  out <- c()
  for (p in path) {
    fext <- file_ext(path)
    compressions <- c("gzip", "gz", "bgz", "zip")
    areCompressed <- fext %in% compressions
    if (areCompressed) {
      ext <- file_ext(file_path_sans_ext(path, compression = FALSE))
      regex <- paste0("*\.",ext,"\.", fext,"$")
    } else {
      regex <- paste0("*\.",fext,"$")
    }
    new <- gsub(pattern = regex, "", path)
    out <- c(out, new)
  }
  return(ifelse(basename, basename(out), out))
}

正在加载所需的库:

> library(stringr)

正在从正则表达式中提取所有匹配项:

> str_match("ABCD.csv", "(.*)\..*$")
     [,1]       [,2]  
[1,] "ABCD.csv" "ABCD"

只返回结果的第二部分,对应匹配文件名的分组:

> str_match("ABCD.csv", "(.*)\..*$")[,2]
[1] "ABCD"

编辑@U-10-Forward:

和那个回答基本是一样的道理。只是我发现这个解决方案更强大。

正则表达式意味着:

  • () = 组

  • .* = 除换行符以外的任何单个字符任意次数

  • // 是转义符号,因此 //.字面意思是“.”

  • .* = 任意字符任意次数

  • $ 表示应该在输入字符串的末尾

那么逻辑就是 return 在“.”之前的组。后跟字符串末尾的一组字符(在本例中等于文件扩展名)。

如果您的文件名有多个(可能的扩展名)并且您只想去掉最后一个扩展名,您可以尝试以下操作。

考虑文件名foo.bar.baz.txt这个

sub('\..[^\.]*$', '', "foo.bar.baz.txt")

会给你留下 foo.bar.baz

fs::path_ext_remove()“删除最后一个扩展名和 returns 路径的其余部分”。

fs::path_ext_remove(c("ABCD.csv", "foo.bar.baz.txt", "d:/Some Dir/ABCD.csv"))

# Produces: [1] "ABCD"             "foo.bar.baz"      "D:/Some Dir/ABCD"

以上答案很好,但我感兴趣的是同时处理数百万条路径的速度最快。似乎通过 this SO question 使用 sub 是从路径中获取文件名的最快方法。然后比较上面三种方法,使用tools::file_path_sans_ext更快。

library(fs)
library(stringr)
library(microbenchmark)

files<-paste0("http://some/ppath/to/som/cool/file/",1:1000,".flac")

microbenchmark(
    fs::path_ext_remove(sub(".*/", "", files)),
    tools::file_path_sans_ext(sub(".*/", "", files)),
    str_extract(files,  '(?<=[/])([^/]+)(?=\.[^.]+)')
    
) 
Unit: milliseconds
                                                expr     min       lq      mean   median      uq     max neval
          fs::path_ext_remove(sub(".*/", "", files)) 10.6273 10.98940 11.323063 11.20500 11.4992 14.5834   100
    tools::file_path_sans_ext(sub(".*/", "", files))  1.3717  1.44260  1.532092  1.48560  1.5588  2.4806   100
 str_extract(files, "(?<=[/])([^/]+)(?=\\.[^.]+)")  7.4197  7.62875  7.985206  7.88835  8.2311  9.4107   100