R得到子串和正则表达式?

时间:2013-03-15 00:40:12

标签: regex string r

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

HelloWorld#you.txt

我想要返回字符串you

这是我的代码:

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

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

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

6 个答案:

答案 0 :(得分:10)

这是一个单线解决方案

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

输出:

you

要解释代码,它会匹配#之前的所有内容,然后将所有字符提取到.,因此最终输出将是中间字符串这就是你要找的东西。

修改

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

答案 1 :(得分:6)

strapplyc 要在#之后立即使用strapplyc中的gsubfn package尝试提取该字词:

> 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"

增加:其他解决方案

答案 2 :(得分:4)

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

> s <- 'HelloWorld#you.and.me.txt'
> gsub('.*#(.*)\\.+.*','\\1', s)
[1] "you.and.me"

答案 3 :(得分:2)

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

您希望regexpr代替字符,而不是项目。

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

答案 4 :(得分:2)

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

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

收率:

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

$`#  :  right2`
character(0)

虽然我认为标签中存在错误但不是实际的返回值。

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

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

$`#  :  .2`
character(0)

答案 5 :(得分: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)。如果文件名不包含井号,则返回空字符串。