19

我有一个包含文件名文本列的 data.frame。我想返回不带路径或文件扩展名的文件名。通常,我的文件名已编号,但不一定非要编号。例如:

df<-data.frame(data=c("a","b"),fileNames=c("C:/a/bb/ccc/NAME1.ext","C:/a/bb/ccc/d D2/name2.ext"))

我想返回相当于

df<-data.frame(data=c("a","b"),fileNames=c("NAME","name"))

但我无法弄清楚使用 gsub 执行此操作的光滑正则表达式。例如,我可以去掉扩展名(前提是文件名以数字结尾):

gsub('([0-9]).ext','',df[,"fileNames"])

虽然我一直在尝试各种模式(通过阅读本网站上的正则表达式帮助文件和类似解决方案),但我无法让正则表达式返回最后一个“/”和第一个“.”之间的文本。非常感谢您对类似问题的任何想法或转发!

我得到的最好的是:

 gsub('*[[:graph:]_]/|*[[:graph:]_].ext','',df[,"fileNames"])

但是这 1) 并没有去掉所有的前导路径字符,并且 2) 依赖于特定的文件扩展名。

4

2 回答 2

37

也许这会让您更接近您的解决方案:

library(tools)
basename(file_path_sans_ext(df$fileNames))
# [1] "NAME1" "name2"

file_path_sans_ext函数来自“工具”包(我相信它通常与 R 一起提供),它将提取到(但不包括)扩展的路径。然后该basename功能将摆脱您的路径信息。

或者,要从中获取file_path_sans_ext并对其进行一些修改,您可以尝试:

sub("(.*\\/)([^.]+)(\\.[[:alnum:]]+$)", "\\2", df$fileNames)
# [1] "NAME1" "name2"

在这里,我已经“捕获”了“fileNames”变量的所有三个部分,因此如果您只需要文件路径,您可以更改"\\2""\\1",如果您只需要文件扩展名,您可以将其更改为"\\3".

于 2013-02-25T18:34:03.130 回答
11

首先,要摆脱“领先路径”,您可以使用basename. 要删除扩展名,您可以使用sub类似于您在问题中的描述:

filenames <- sub("\\.[[:alnum:]]+$", "", basename(as.character(df$fileNames)))

请注意,您应该使用sub而不是gsub此处,因为每个文件名的文件扩展名只能出现一次。此外,您应该使用\\.which 匹配一个点,而不是使用.which 匹配任何符号。最后,您应该附加$到模式以确保仅当扩展名位于文件名末尾时才删除它。

编辑:file_path_sans_ext Ananda Mahto 的解决方案中建议的功能通过 工作sub("([^.]+)\\.[[:alnum:]]+$", "\\1", x)保留文件名的非扩展名部分,而不是像上面那样删除扩展名。在 OP 的情况下,我看不到这两种方法的任何具体优点或缺点。

于 2013-02-25T18:33:27.140 回答