字符串匹配:单词+字符

时间:2019-01-14 16:16:19

标签: r string string-matching

我正在尝试搜索数据框以匹配字符串,我在其中用填充笔记的列中创建了一个对象。

例如:

我正在寻找注释可能匹配的任何行

mph_words<-c(">10", "> 10", ">20", "> 20")

一行代码可能类似于:

> lc_notes[1703]
[1] "collected 1.667 man-hr total. mostly cloudy, windy with gusts >20 mph."

如您所见,某些注释在数字“ <”或“>”与数字之间有空格,因此使用strsplit搜索不是理想的,因为我确实需要将“ <” /“>”与号码。

我尝试过

> mph_words %in% lc_notes[2000]
[1] FALSE FALSE FALSE FALSE

> pmatch(mph_words, lc_notes[1703])
[1] NA NA NA NA

grepl(lc_notes[1703],mph_words)
[1] FALSE FALSE FALSE FALSE

> str_detect(mph_words,lc_notes[1703])
[1] FALSE FALSE FALSE FALSE

> for (word in 1:length(mph_words)){
+   print(str_extract(mph_words[word],lc_notes[1703]))
+ }
[1] NA
[1] NA
[1] NA
[1] NA

,我不确定接下来要尝试什么。如果它是一个正则表达式,您可以在回答中解释一下吗?我试图更好地了解正则表达式。

编辑 我正在尝试打印出明确包含mph_words中的字符之一的行。因此,该代码将搜索我的lc_notes中的每一行并打印行1703。

提前谢谢!

3 个答案:

答案 0 :(得分:3)

已编辑,以匹配已编辑的问题:
要查找行号,请使用grep

grep("[<>]\\s*\\d+\\b",  lc_notes)

[<>]匹配<或>
\\s*允许可选的空格
\\d与以下数字匹配。

grep将给出匹配的行号。

答案 1 :(得分:2)

为此,我将applystringr::str_detect一起使用:

lc_notes <- c("collected 1.667 man-hr total. mostly cloudy, windy with gusts >20 mph.",
              "collected 1.667 man-hr total. mostly cloudy, windy with gusts > 20 mph.",
              "collected 1.667 man-hr total. mostly cloudy, windy with gusts of 20 mph.")
mph_words<-c(">10", "> 10", ">20", "> 20")

sapply(lc_notes, function(x) any(str_detect(x, mph_words)))

collected 1.667 man-hr total. mostly cloudy, windy with gusts >20 mph. 
                                                                    TRUE 
collected 1.667 man-hr total. mostly cloudy, windy with gusts > 20 mph. 
                                                                    TRUE 
collected 1.667 man-hr total. mostly cloudy, windy with gusts of 20 mph. 
                                                                   FALSE 

sapply将遍历lc_notes向量的每个元素,并将测试应用于每个元素。然后使用any,将向量简化为单个逻辑值。

如果要行号而不是逻辑矢量,请使用which函数:

unname(which(sapply(lc_notes, function(x) any(str_detect(x, mph_words)))))
[1] 1 2

我在这里使用unname来强调此返回的向量是lc_notes中与任何正则表达式模式匹配的项的索引。您也可以执行相反的操作并对其调用names以突出显示该行的文本:

names(which(sapply(lc_notes, function(x) any(str_detect(x, mph_words)))))
[1] "collected 1.667 man-hr total. mostly cloudy, windy with gusts >20 mph." 
[2] "collected 1.667 man-hr total. mostly cloudy, windy with gusts > 20 mph."

如果您想要一个更简单的正则表达式,可以匹配或不匹配空格,请在空格字符上使用?可选量词:

mph_words<-c("> ?10", "> ?20")

答案 2 :(得分:1)

这是使用strsplitlapply的一种方式

# standardize (get rid of white spaces between <,> and digits in mph_words
mph_words <- unique(gsub('([<>])\\s{0,}(\\d+)', '\\1\\2', mph_words, perl = TRUE))        
# match 
check <- lapply(1:length(lc_notes), 
                function (k) any(mph_words %in% unlist(strsplit(lc_notes[k], ' '))))
check
# [[1]]
# [1] TRUE

# [[2]]
# [1] TRUE

# [[3]]
# [1] FALSE

# Finally printing the indices with a match
which(unlist(check))
# [1] 1 2

带有数据

mph_words <- c(">10", "> 10", ">20", "> 20")  
lc_notes <- "collected 1.667 man-hr total. mostly cloudy, windy with gusts >20 mph."
lc_notes <- c(lc_notes, 'test >10', '>15')