R中的REGEX:从字符串中提取单词

时间:2015-11-22 14:55:58

标签: regex r string extract

我想这是一个常见的问题,我发现了很多网页,包括一些来自SO的网页,但我不明白如何实现它。

我是REGEX的新手,我想在R中使用它来从句子中提取前几个单词。

例如,如果我的句子是

z = "I love stack overflow it is such a cool site"

我想输出我的输出(如果我需要前四个单词)

[1] "I love stack overflow"

或(如果我需要最后四个字)

[1] "such a cool site"

当然,以下作品

paste(strsplit(z," ")[[1]][1:4],collapse=" ")
paste(strsplit(z," ")[[1]][7:10],collapse=" ")

但是我想尝试使用正则表达式解决方案来解决性能问题,因为我需要处理非常大的文件(以及为了了解它)

我查看了几个链接,包括 Regex to extract first 3 words from a stringhttp://osherove.com/blog/2005/1/7/using-regex-to-return-the-first-n-words-in-a-string.html

所以我尝试过像

这样的事情
gsub("^((?:\S+\s+){2}\S+).*",z,perl=TRUE)
Error: '\S' is an unrecognized escape in character string starting ""^((?:\S"

我尝试了其他东西,但它通常会将整个字符串或空字符串返回给我。

substr的另一个问题是它返回一个列表。也许看起来[[]]运算符在处理大文件和应用东西时会慢一点(??)。

看起来R中使用的语法有些不同? 谢谢!

2 个答案:

答案 0 :(得分:6)

您已经接受了答案,但我将分享这个作为帮助您更多了解R中正则表达式的一种方法,因为您实际上已经非常接近您的答案自己的。

gsub方法存在两个问题:

  1. 您使用了单个反斜杠(\)。 R要求你逃避它们,因为它们是特殊字符。你通过添加另一个反斜杠(\\)来逃避它们。如果您执行nchar("\\"),则会看到它返回" 1"。

  2. 您没有说明替换应该是什么。在这里,我们不想替换任何东西,但我们想要捕获字符串的特定部分。您可以在括号(...)中捕获组,然后您可以通过组的编号来引用它们。在这里,我们只有一个组,因此我们将其称为"\\1"

  3. 你应该尝试过类似的东西:

    sub("^((?:\\S+\\s+){2}\\S+).*", "\\1", z, perl = TRUE)
    # [1] "I love stack"
    

    这基本上是在说:

    • 从" z"。
    • 的内容开始工作
    • 开始创建第1组。
    • 查找非空格(如单词),后跟空格(\S+\s+)两次{2},然后查找下一组非空格(\S+)。这将得到3个单词,而不是在第三个单词之后得到空格。因此,如果您想要不同数量的单词,请将{2}更改为比您实际使用的数字少一个。
    • 在那里结束第1组。
    • 然后,只需从" z"返回第1组(\1)的内容。

    要获取最后三个单词,只需切换捕获组的位置并将其放在模式的末尾即可。

    sub("^.*\\s+((?:\\S+\\s+){2}\\S+)$", "\\1", z, perl = TRUE)
    # [1] "a cool site"
    

答案 1 :(得分:3)

获得前四个单词。

library(stringr)
str_extract(x, "^\\s*(?:\\S+\\s+){3}\\S+")

获得最后四个。

str_extract(x, "(?:\\S+\\s+){3}\\S+(?=\\s*$)")