我想这是一个常见的问题,我发现了很多网页,包括一些来自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 string和 http://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中使用的语法有些不同? 谢谢!
答案 0 :(得分:6)
您已经接受了答案,但我将分享这个作为帮助您更多了解R中正则表达式的一种方法,因为您实际上已经非常接近您的答案自己的。
gsub
方法存在两个问题:
您使用了单个反斜杠(\
)。 R要求你逃避它们,因为它们是特殊字符。你通过添加另一个反斜杠(\\
)来逃避它们。如果您执行nchar("\\")
,则会看到它返回" 1"。
您没有说明替换应该是什么。在这里,我们不想替换任何东西,但我们想要捕获字符串的特定部分。您可以在括号(...)
中捕获组,然后您可以通过组的编号来引用它们。在这里,我们只有一个组,因此我们将其称为"\\1"
。
你应该尝试过类似的东西:
sub("^((?:\\S+\\s+){2}\\S+).*", "\\1", z, perl = TRUE)
# [1] "I love stack"
这基本上是在说:
\S+\s+
)两次{2}
,然后查找下一组非空格(\S+
)。这将得到3个单词,而不是在第三个单词之后得到空格。因此,如果您想要不同数量的单词,请将{2}
更改为比您实际使用的数字少一个。\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*$)")