r - 使用正则表达式提取特定字符串

标签 r regex

我有一个包含字符串和 POS 标签的数据名。我想通过过滤特定的 POS 标签来提取特定的字符串。

举一个简单的例子,我想提取以“NN-NN-NN”和“VB-JJ-NN”为基础的字符串。

df <- data.frame(word = c("abrasion process management", 
                          "slurries comprise abrasive", 
                          "slurry compositions comprise ", 
                          "keep high polishing", 
                          "improved superabrasive grit", 
                          "using ceriacoated silica",
                          "and grinding",
                          "for cmp",
                          "and grinding for"),
                 pos_tag = c("NN-NN-NN", "NNS-NN-NN", "NN-NNS-NN", "VB-JJ-NN", 
                             "VBN-JJ-NN", "VBG-JJ-NN", "CC-VBG", "IN-NN", "CC-VBG-IN"))

> df
               word              pos_tag
1   abrasion process management  NN-NN-NN
2    slurries comprise abrasive  NNS-NN-NN
3 slurry compositions comprise   NN-NNS-NN
4           keep high polishing  VB-JJ-NN
5   improved superabrasive grit  VBN-JJ-NN
6      using ceriacoated silica  VBG-JJ-NN
7                  and grinding  CC-VBG
8                       for cmp  IN-NN
9              and grinding for  CC-VBG-IN

我尝试使用正则表达式来定义我的模式。 但我认为这不是定义模式的有效方法。 还有其他更有效的方法吗?

pos <- c("NN-NN-NN", "NNS-NN-NN", "NN-NNS-NN", "VB.-JJ-NN", "VB-JJ-NN")
pos2 <- paste0('^', pos , "\\w*$", collapse = '|')
sort_string <- df[grep(pos2,  df$pos_tag),] %>%
               unique()

这就是我想要得到的

               word              pos_tag
1   abrasion process management  NN-NN-NN
2    slurries comprise abrasive  NNS-NN-NN
3 slurry compositions comprise   NN-NNS-NN
4           keep high polishing  VB-JJ-NN
5   improved superabrasive grit  VBN-JJ-NN
6      using ceriacoated silica  VBG-JJ-NN

最佳答案

您不需要为此使用正则表达式。一种可能性是使用 stringdist 包中的 amatch 函数:

vec <- c("NN-NN-NN", "VB-JJ-NN")

library(stringdist)
df[!!amatch(df$pos_tag, vec, maxDist = 1, nomatch = 0),]

给出:

                           word   pos_tag
1   abrasion process management  NN-NN-NN
2    slurries comprise abrasive NNS-NN-NN
3 slurry compositions comprise  NN-NNS-NN
4           keep high polishing  VB-JJ-NN
5   improved superabrasive grit VBN-JJ-NN
6      using ceriacoated silica VBG-JJ-NN

它的作用:

  • amatch(df$pos_tag, vec, maxDist = 1, nomatch = 0) 查看 df$pos_tag 中的值是否与 vec 中的值匹配code> 具有指定的差异容差。
  • 在本例中,我使用了 1 个字符的最大允许编辑距离:maxDist = 1
  • 通过双重否定,!! 创建一个逻辑向量,指示 pos_tag 是否(几乎)与 vec 中的某个值匹配。另一种方法是:df[amatch(df$pos_tag, vec, maxDist = 1, nomatch = 0) > 0,]

您还可以在基础 R 中使用 agrep/agrepl 结合 sapply/lapply 来完成此操作rowSums/取消列出:

# method 1:
df[rowSums(sapply(vec, function(x) agrepl(x, df$pos_tag, max.distance = 1))) > 0,]

# method 2:
df[unlist(lapply(vec, function(x) agrep(x, df$pos_tag, max.distance = 1))),]

两者都会给你相同的结果。

关于r - 使用正则表达式提取特定字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46580598/

相关文章:

java - 正则表达式 : who's greedier?

r - 获取 R 脚本的路径

regex - FluentD 日期时间格式不匹配

r - 处理不完整的案例并进行估算?

c - R 外部接口(interface)

javascript - JS 上的正则表达式未替换

JavaScript 正则表达式替换字符串中的最后一个模式?

regex - 在与 sed 的最后一场比赛之后追加行

r - 如何在R中从具有多个条件的一个数据帧创建多个数据帧

R:按字母顺序重新排序因子的级别,但一个