正则表达式返回文件名,删除路径和文件扩展名。

21
我有一个数据框,其中包含文件名的文本列。我想返回不带路径或文件扩展名的文件名。通常,我的文件名已编号,但不必如此。例如:
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"])

但是这种方法不能完全去除前导路径字符,并且依赖于特定的文件扩展名。

2个回答

40
也许这可以让您更接近解决方案:
library(tools)
basename(file_path_sans_ext(df$fileNames))
# [1] "NAME1" "name2"

file_path_sans_ext函数来自于“tools”包(我相信这个包通常会随R一起安装),它可以提取路径,但不包括扩展名。然后使用basename函数就可以去掉路径信息。

或者,你可以从file_path_sans_ext函数中进行修改:

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

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

有趣的方法。对我来说,这种方法比正则表达式更清晰,目前正则表达式对我来说有点困惑。我会试一试。 - Docuemada
这个很好用,谢谢。对我来说更有意义,但这可能是因为我需要更多的正则表达式练习! - Docuemada
@Docuemada,没问题。如所示,file_path_sans_ext是一个基本的正则表达式,我怀疑basename也是(但还没有检查验证)。 - A5C1D2H2I1M1N2O1R2T1
是的!sub("(.*\/)([^.]+)(\.[[:alnum:]]+$)", "\2", df$fileNames) 就是我想要的。感谢您和 zipfzapf 快速而详细的回复。 - Docuemada

11

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

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

请注意,在此处应使用sub而不是gsub,因为每个文件名只能出现一次文件扩展名。此外,您应该使用匹配点的\\.而不是匹配任何符号的.。最后,您应该在模式中添加$,以确保仅在文件名的末尾删除扩展名。 编辑: Ananda Mahto的解决方案中建议使用file_path_sans_ext函数通过sub(“([^。]+)\。 [[:alnum:]] + $”,“ \\ 1”,x)工作,即保留文件名的非扩展部分,而不是像上面那样删除扩展名。在OP的情况下,我看不到两种方法的特定优缺点。

1
如果df$fileNames被读入为因子变量,就像提供的示例数据一样,你可能需要在其周围使用as.character - A5C1D2H2I1M1N2O1R2T1
谢谢您,也感谢您解释正则表达式字符。这很有效。对于这个例子,我使用了...as.character(df$fileNames)。 - Docuemada

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接