9

我有一组作为文件名的字符串。我想提取 # 符号之后但文件扩展名之前的所有字符。例如,其中一个文件名是:

HelloWorld#you.txt

我想返回字符串you

这是我的代码:

    hashPos = grep("#", name, fixed=TRUE)
    dotPos = length(name)-3
    finalText = substring(name, hashPos, dotPos)

我在网上读到grep应该返回第一个参数出现的索引(在这种情况下是 # 符号)。所以,我期待上述工作,但它没有。

或者我将如何使用正则表达式来提取这个字符串?另外,当字符串没有# 符号时会发生什么?该函数是否会返回一个特殊的值,例如 -1?

4

6 回答 6

17

这是一个单行解决方案

gsub(".*\\#(.*)\\..*", "\\1", c("HelloWorld#you.txt"))

输出:

you

为了解释代码,它将匹配所有内容#,然后提取所有单词字符.,因此最终输出将是您正在寻找的中间字符串。

编辑

上述解决方案将文件名匹配到最后一个,.即允许文件名有多个点。如果要将名称提取到第一个名称,.则可以改用正则表达式.*\\#(\\w*)\\..*

于 2013-03-15T00:47:07.997 回答
6

strapplyc要在#尝试使用gsubfn中的strapplyc 后立即提取单词:

> library(gsubfn)
>
> strapplyc("HelloWorld#you.txt", "#(\\w+)")[[1]]
[1] "you"

或者这允许文件名包含点:

> strapplyc("HelloWorld#you.txt", "#(.*)\\.")[[1]]
[1] "you"

file_path_sans_ext 使用工具包(与 R 捆绑在一起,因此不需要安装额外的包)的另一种更面向文件名的方法如下:

> library(tools)
>
> file_path_sans_ext(sub(".*#", "", "HelloWorld#you.txt")) 
[1] "you"

添加:其他解决方案

于 2013-03-15T00:51:11.440 回答
4

您可以使用gsub. 这样做的好处是您可以匹配多个.s 直到最后一个。

> s <- 'HelloWorld#you.and.me.txt'
> gsub('.*#(.*)\\.+.*','\\1', s)
[1] "you.and.me"
于 2013-03-15T00:49:17.023 回答
2

grep根据项目编号返回索引,而不是字符位置(HelloWorld#you.txt 只有一项,所以它应该返回 1)。

相反,您希望regexpr它计算字符而不是项目。

hashPos = regexpr("#", name, fixed=TRUE) + 1
dotPos = length(name)-3
finalText = substring(name, hashPos, dotPos)
于 2013-03-15T00:44:02.463 回答
2

对于那些不想学习正则表达式但不符合发布者意图的人来说,这个解决方案很容易(对于未来的搜索者来说更多)。这种方法涵盖了您没有的情况,#因为函数将返回character(0)

library(qdap)
x <- c("HelloWorld#you.txt", "HelloWorldyou.txt")
genXtract(x, "#", ".")

产量:

> genXtract(x, "#", ".")
$`#  :  right1`
[1] "you"

$`#  :  right2`
character(0)

虽然我认为标签中存在错误,但实际返回值没有。

编辑:这确实是一个已在开发版本中修复的错误。输出与发展。版本:

> genXtract(x, "#", ".")
$`#  :  .1`
[1] "you"

$`#  :  .2`
character(0)
于 2013-03-15T01:56:00.830 回答
0

到目前为止,我不喜欢这里的大多数解决方案。他们要么使用过于复杂的正则表达式,要么使用额外的软件包,恕我直言,这是不必要的。我认为这里更重要,更可重用

# Function that finds a match and returns the matched string
getMatch = function(rexp, str) regmatches(str, regexpr(rexp, str))

filename = "HelloWorld#you.txt"

# The regexp here is simply the hash sign plus everything 
# following that is not a dot
getMatch("#[^.]*", filename)

#you按原样返回(您可以#使用substr函数删除)。如果文件名不包含井号,则返回空字符串。

于 2021-06-18T09:20:42.453 回答