2012-03-02 172 views
26

在R中,grep通常匹配多个字符串对一个正则表达式的向量。R grep:匹配多个模式的一个字符串

问:是否有可能将单个字符串与多个正则表达式匹配? (没有循环遍历每一个正则表达式模式)?

一些背景资料:

我有7000+的关键词作为指标的几个类别。我无法更改该关键字字典。这本字典有以下结构(关键字在第1栏的数字代表这些关键字属于类别):

ab 10 37 41 
abbrach* 38 
abbreche 39 
abbrich* 39 
abend* 37 
abendessen* 60 63 
aber 20 23 45 
abermals 37 

串联有这么多的关键字“|”不是一个可行的方法(我不知道哪个关键字产生了命中)。 此外,只是反转“模式”和“字符串”不起作用,因为模式具有截断,这不会反过来工作。

[related question,其他编程语言]

+2

我就像丹的建议一样,但是对于大数据集,您可能会遇到一些重大的速度问题。如果您想在字典中查找某些内容并返回对应的值,我会建议采用不同的方法:使用strsplit将句子分解为单个单词的向量,然后应用哈希表进行快速查找。我在想,你可能想把关键字和类别指标分成两个单独的字典列。我会在那里提供帮助,但只有在你更清楚地将最终结果作为想要之后。 – 2012-03-02 18:33:04

+0

同意重构字典数据并使用散列表进行查找(取决于期望的结果),但匹配应该相对较快,具体取决于字符串的数量,即使使用大量关键字也是如此。我会为我的答案添加一个快速基准。 – danpelota 2012-03-02 19:33:03

+1

如果你真的有很多单词 (通常是人类语言中的所有单词, 所有被google索引的单词等),你可以使用 [前缀树](http:// en。 wikipedia.org/wiki/Trie) (它有时也被称为“trie”)。 但我不知道任何实现的R. – 2012-03-02 23:25:46

回答

28

怎么样了关键字的矢量应用regexpr功能?返回

keywords <- c("dog", "cat", "bird") 

strings <- c("Do you have a dog?", "My cat ate by bird.", "Let's get icecream!") 

sapply(keywords, regexpr, strings, ignore.case=TRUE) 

    dog cat bird 
[1,] 15 -1 -1 
[2,] -1 4 15 
[3,] -1 -1 -1 

    sapply(keywords, regexpr, strings[1], ignore.case=TRUE) 

dog cat bird 
    15 -1 -1 

值是在比赛的第一个字符的位置,与-1意义不匹配。

如果匹配的位置是无关紧要的,使用grepl代替:

sapply(keywords, grepl, strings, ignore.case=TRUE) 

     dog cat bird 
[1,] TRUE FALSE FALSE 
[2,] FALSE TRUE TRUE 
[3,] FALSE FALSE FALSE 

更新:这将运行在我的系统比较快,即使有大量的关键字:

# Available on most *nix systems 
words <- scan("/usr/share/dict/words", what="") 
length(words) 
[1] 234936 

system.time(matches <- sapply(words, grepl, strings, ignore.case=TRUE)) 

    user system elapsed 
    7.495 0.155 7.596 

dim(matches) 
[1]  3 234936 
+0

谢谢您的回答与您的意见!最后,我做了一个综合的方法:将一组可能的匹配减少到原始大小的〜5%,并且sapply函数完成了grep。 – 2012-03-05 10:13:31

+0

然后为了查看每个句子/字符串中有多少个关键字与最终数据帧匹配,问题: num.matches < - apply(data.frame(matches),1,function(z)sum( ž== TRUE)) 。并且查找哪个原始字符串有,比方说,2个匹配,问题: strings [num.matches == 2]#输出:[1]“我的猫吃了鸟。” – 2014-04-05 11:41:34

+0

如果你想做一个替代品,你不只是阅读关键字来搜索,而且他们的替代品? – user1603472 2017-08-11 11:31:03

2

要扩展other answer,要将sapply()输出转换为有用的逻辑向量,您需要进一步使用apply()步骤。

keywords <- c("dog", "cat", "bird") 
strings <- c("Do you have a dog?", "My cat ate by bird.", "Let's get icecream!") 
(matches <- sapply(keywords, grepl, strings, ignore.case=TRUE)) 
#  dog cat bird 
# [1,] TRUE FALSE FALSE 
# [2,] FALSE TRUE TRUE 
# [3,] FALSE FALSE FALSE 

要知道哪些字符串包含关键字的任何(模式):

apply(matches, 1, any) 
# [1] TRUE TRUE FALSE 

要知道哪些关键字(模式)中提供的字符串相匹配:

apply(matches, 2, any) 
# dog cat bird 
# TRUE TRUE TRUE