【问题标题】:REGEX in R: extracting words from a stringR中的正则表达式:从字符串中提取单词
【发布时间】:2016-02-24 16:19:23
【问题描述】:

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

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

例如,如果我的句子是

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

id 喜欢让我的输出保持原样(如果我需要前四个单词)

[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 中使用的语法有些不同? 谢谢!

【问题讨论】:

  • 您需要在 R 正则表达式中使用双重转义。 \S -> \\S
  • 您也可以尝试stringi::stri_extract_all_words(z)[[1]][1:4],它更易于使用且不需要了解正则表达式。虽然你会得到一个单独的值。
  • 你不能使用我分享的相同想法in your earlier question吗?正如@stribizhev 已经指出的那样,您只需将 R 中的反斜杠加倍。
  • 是的@Ananda Mahto 抱歉,我学得很慢,现在我知道我需要双反斜杠

标签: regex r string extract


【解决方案1】:

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


您的gsub 方法存在两个问题:

  1. 您使用了单反斜杠 (\)。 R 要求您将其转义,因为它们是特殊字符。您可以通过添加另一个反斜杠 (\\) 来转义它们。如果您执行nchar("\\"),您会看到它返回“1”。

  2. 您没有指定替换的内容。在这里,我们不想替换任何东西,但我们想捕获字符串的特定部分。您在括号(...) 中捕获组,然后您可以通过组的编号来引用它们。在这里,我们只有一组,所以我们称之为"\\1"

你应该尝试过类似的方法:

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"

【讨论】:

  • 谢谢。 @Ananda Mahto。您能否使用相同的函数sub 给出最后 4 个单词的正则表达式?
  • @FaguiCurtain,我只是将引用从固定到行首换到了行尾,例如:^.*((?:\\S+\\s+){2}\\S+)$。将“2”更改为“3”以获得 4 个单词而不是 3 个。
【解决方案2】:

用于获取前四个单词。

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

为了获得最后四个。

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

【讨论】:

  • sub("^\\s*((?:\\S+\\s+){3}\\S+).*", "\\1", x)
  • 你能用sub函数给我正确的正则表达式吗?我对 10,000 个样本进行了测试,基础 R 中的 sub 函数比 library(stringr) 中的 str_extract 快 30 倍。谢谢
  • 我很愚蠢,但不知道如何调整功能。 sub("(?:\\S+\\s+){3}\\S+(?=\\s*$)",replacement="",z,perl=TRUE) 正在返回我 "I love stack overflow it is " 这是除了最后 4 个字之外的所有内容......
  • sub('^.* (\\w+\\s+\\w+\\s+\\w+\\s+\\w+)$', '\\1', z) 适用于最后 5 个字符串,但我不明白如何正确使用 {...} 在这种情况下使表达式更简单
  • 点赞sub('^.* (\\w+(?:\\s+\\w+){4})$', '\\1', z)
猜你喜欢
  • 2011-03-09
  • 1970-01-01
  • 2017-08-09
  • 1970-01-01
  • 1970-01-01
  • 2019-03-18
  • 1970-01-01
  • 2015-03-18
  • 2021-10-27
相关资源
最近更新 更多