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

时间:2017-10-05 07:55:35

标签: 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

1 个答案:

答案 0 :(得分:2)

您不需要正则表达式。可能是使用amatch - 包中的stringdist - 函数:

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中的值匹配,且差异达到了指定的容差。
  • 在这种情况下,我使用了最多允许的1个字符的editdistance:maxDist = 1
  • 通过双重否定,!!创建一个逻辑向量,指示pos_tag(几乎)是否与vec中的某个值匹配。另一种方法是:df[amatch(df$pos_tag, vec, maxDist = 1, nomatch = 0) > 0,]

您也可以在基座R中将agrep / agreplsapply / lapplyrowSums / unlist结合使用:

# 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))),]

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