R:grep意外地输出了多个字符串匹配项

时间:2019-05-15 13:20:35

标签: r string grep match lapply

我有一个带有1个变量和5,000行的数据框,其中每个元素都是一个字符串。

1. "Am open about my feelings."                   
2. "Work hard"                                 
3. "Work harder than others."
   .....
5000. "Speak softly."           

我需要找到并输出与多个元素相对应的行索引,即每个精确匹配的元素一个行索引。当前,我使用以下功能:

z <- lapply(df, function(p) {
     grep(pattern = p, test[ , 1])})

它运行良好,并为我要查找的每个元素输出行索引。但是我注意到它变得贪婪,因此代码不仅找到确切的字符串,而且还找到恰好包含原始字符串的较大字符串。例如,如果代码正在搜索元素“努力工作”的行索引,则它将输出2个行索引。一个用于精确匹配,另一个用于包含原始字符串的“更大的字符串”。

[1] 2 3

到目前为止,我仅部分解决了该问题:

我在网站上搜索了许多与grep相关的线程,找到了一个可行的解决方案,但一次只能找到一个字符串短语的完全匹配项。

grep("\\bWork hard*\\b", df$value)

由于这不是一个有效的解决方案,因此我想寻求帮助来调整lapply代码,使其仅查找确切的字符串。我还尝试在lapply代码的各个部分中添加“ \\ b”和“ * \\ b”,但未成功。

编辑。添加了可复制的示例

test_1是包含将近5000个字符串元素的数据框,但对于
 一个小的可复制示例,我将仅提供5个字符串元素

test_1 <- c( 
         "Like to watch children open presents.",         
          "Work hard.",                              
          "Work harder after a failure.",                   
          "Am open about my feelings.",                
          "Show my sadness.")

library(dplyr)

test_1 <- tbl_df(test_1) # tablulate as datafarme 

df是一个具有3个字符串值的字符对象:

df <- c("Work hard.", 
        "Show my sadness.", 
        "Like to watch children open presents.")

以下是获取df每个元素的函数,可在test_1中找到其匹配项  并从test_1输出相应的行索引

j <- lapply(df, function(p) {
grep(pattern = p, test_1[ , 1])})
j

# Output
[[1]]
[1] 2 3 # as you see it finds two matches. One is the exact match: "Work hard." row index 2. Another one is a larger string that contains wording of the original string: row index 3. But I only want an exact match, i.e. index 2

[[2]]
[1] 5

[[3]]
[1] 1

我想要的是:每个完全匹配的元素都有一个单行索引

[[1]]
[1] 2 

[[2]]
[1] 5

[[3]]
[1] 1

1 个答案:

答案 0 :(得分:1)

因此,使用lapplygrep可以使用以下代码:

lapply(df, function(z) grep(paste0("^",z,"$"), test_1))

结果是

[[1]]
[1] 2

[[2]]
[1] 5

[[3]]
[1] 1

这通过使用锚点起作用。 ^是字符串开头的锚点,$是字符串结尾的锚点。使用paste0将锚点与df中感兴趣的字符串组合在一起以创建以下内容:

[1] "^Work hard.$"                            "^Show my sadness.$"                      "^Like to watch children open presents.$"

并通过将搜索范围限制为^$之间的任何内容来搜索整个字符串。