如何根据条件从文本中提取字符串向量的所有实例

时间:2019-03-30 04:23:14

标签: r regex string text-extraction

我对R还是比较陌生,并尝试根据以下条件从文本(数据框的一列)中提取一些字符串,并将它们与名称(这是数据框的另一列)一起存储:

我正在尝试做的一个简化示例如下:

textdf <- data.frame(names = letters[1:4], text = c("I'm trying to extract flowers from text", 
                                                "there are certain conditions on how to extract", 
                                                "this red rose is also nice-smelling", 
                                                "scarlet rose is also fine"))

extractdf <- data.frame(extractions = c("extract", "certain", "certain conditions", 
                                        "nice-smelling rose", "red rose"), 
                        synonyms = c(NA, NA, NA, NA, "scarlet rose"))

我想

  1. 在“提取”列中查找并提取所有实例 出现在我df的“文本”列中。

  2. 如果一行不匹配,请说“红色”不匹配     玫瑰”,我想寻找同义词,以防“ scarlet”     玫瑰”。

  3. 对于具有相同“ FIRST”单词的短语,我想提取最长的短语 子字符串...例如,如果我同时拥有“某些”和     “某些条件”我要保留“某些条件”。
  4. 还提取“香玫瑰”吗?
  5. 最后,我想将所有提取存储在一个单独的列中 df或获取命名列表也可以。

所以我需要的是这个

#result
textdf <- data.frame(names = letters[1:4], text = c("I'm trying to extract flowers from text", 
                                                "there are certain conditions on how to extract", 
                                                "this red rose is also nice-smelling", 
                                                "scarlet rose is also fine"), 
                     ex = c("extract", "certain conditions, extract", "nice-smelling rose, red rose", "scarlet rose"))

我尝试过:

##for the first item
library(rebus)
library(stringi)
sapply(textdf$text, function(x) stri_extract_all_regex(x, or1(extractdf$extractions)))

这找到了“某些”但没有“某些条件”

##for the second and fourth item
library(stringdist)
Match_Idx = amatch(textdf$text, extractdf$extractions, method = 'lcs', maxDist = Inf)
Matches = data.frame(textdf$text, extractdf$extractions[Match_Idx])

这很不错,因为它同时提取了“某些情况”和“好闻的玫瑰”,但问题是这样的:如果我在文本中同时拥有“某些情况”和“好闻的玫瑰”怎么办?我如何才能找到两者?

我不知道第三个单词该怎么做...我必须同时标记文本和提取内容,找到唯一的第一个单词,然后提取最长的匹配项吗???

对于您在解决任何项目方面的帮助或在自定义函数中将它们全部获得的帮助,我将不胜感激。

1 个答案:

答案 0 :(得分:0)

您可以使用放入向量中的正则表达式

rex <- c("(extract)", "((?>(?>red)|(?>scarlet))\\srose)", 
         "(\\bcertain\\sconditions\\b)", 
         "((?>rose).*(?>nice-smelling)|(?>nice-smelling).*(?>rose))")

创建匹配函数

fun <- function(x, y) regmatches(x, regexpr(y, x, perl=TRUE))

并与outer一起应用。

M <- outer(textdf$text, rex, Vectorize(fun))

现在我们应该稍微清洁一下矩阵,这取决于您的数据,例如

M[grep("((?>rose)*.(?>nice-smelling)|(?>nice-smelling).*s(?>rose))", 
       M, perl=TRUE)] <- "nice-smelling rose"

最后折叠结果矩阵并将新矢量添加到数据框中。

textdf$ex <- apply(M, 1, function(x) toString(unlist(x)))

给予

textdf
#   names                                           text                           ex
# 1     a        I'm trying to extract flowers from text                      extract
# 2     b there are certain conditions on how to extract  extract, certain conditions
# 3     c            this red rose is also nice-smelling red rose, nice-smelling rose
# 4     d                      scarlet rose is also fine                 scarlet rose