1

我有一个功能:

ncount <- function(num = NULL) {

 toRead <- readLines("abc.txt")
 n <- as.character(num)
 x <- grep("{"n"} number",toRead,value=TRUE)

}

在 grep-ing 时,我希望函数中传递的 num 动态创建要搜索的模式?如何在 R 中做到这一点?文本文件的每一行都有数字和文本

4

2 回答 2

5

您可以paste用来连接字符串:

grep(paste("{", n, "} number", sep = ""),homicides,value=TRUE)
于 2013-01-30T12:47:20.213 回答
0

为了从 R 中的变量构建正则表达式,在当前场景中,您可以使用以下方法简单地将字符串文字与变量连接paste0

grep(paste0('\\{', n, '} number'), homicides, value=TRUE)

请注意,它{是括号表达式之外的特殊字符[...](也称为字符类),如果您需要查找文字{字符,则应将其转义。

如果您使用项目列表作为替代列表,您可以使用/的组合pastepaste0

words <- c('bananas', 'mangoes', 'plums')
regex <- paste0('Ben likes (', paste(words, collapse='|'), ')\\.')

生成的Ben likes (bananas|mangoes|plums)\.正则表达式将匹配Ben likes bananas.,Ben likes mangoes.Ben likes plums.. 请参阅R 演示正则表达式演示

注意:PCRE(当您传递perl=TRUE给基本 R 正则表达式函数时)或 ICU(stringr / stringi正则表达式函数)已证明可以更好地处理这些场景,建议使用这些引擎而不是基本 R 正则表达式函数中使用的默认 TRE 正则表达式库.

通常,您会希望构建一个包含应完全匹配的单词列表的模式,作为整个单词。在这里,很大程度上取决于边界的类型以及单词是否可以包含特殊的正则表达式元字符,它们是否可以包含空格。

在最一般的情况下,单词边界 ( \b)效果很好。

regex <- paste0('\\b(', paste(words, collapse='|'), ')\\b')
unlist(regmatches(examples, gregexpr(regex, examples, perl=TRUE)))
## => [1] "bananas" "mangoes" "plums"  

\b(bananas|mangoes|plums)\b模式将匹配bananas,但不会匹配 banana(请参阅R 演示)。

如果你的清单像

words <- c('cm+km', 'uname\\vname')

您必须先转义单词,即\在每个元字符之前附加:

regex.escape <- function(string) {
  gsub("([][{}()+*^$|\\\\?.])", "\\\\\\1", string)
}
examples <- c('Text: cm+km, and some uname\\vname?')
words <- c('cm+km', 'uname\\vname')
regex <- paste0('\\b(', paste(regex.escape(words), collapse='|'), ')\\b')
cat( unlist(regmatches(examples, gregexpr(regex, examples, perl=TRUE))) )
## => cm+km uname\vname 

如果您的单词可以以特殊的正则表达式元字符开头或结尾,则\b单词边界将不起作用。采用

  • 明确的单词边界(?<!\w)/ (?!\w),当非单词字符或字符串的开始/结束之间预期匹配时
  • 空白边界, (?<!\S)/ (?!\S),当匹配应包含空白字符或字符串的开始/结束时
  • 使用lookbehind/lookahead组合和您的自定义字符类/括号表达式构建您自己的,甚至更复杂的模式。

R 中前两种方法的示例(替换为用<<and括起来的匹配项>>):

regex.escape <- function(string) {
  gsub("([][{}()+*^$|\\\\?.])", "\\\\\\1", string)
}
examples <- 'Text: cm+km, +km and C++,Delphi,C++CLI and C++/CLI.'
words <- c('+km', 'C++')
# Unambiguous word boundaries
regex <- paste0('(?<!\\w)(', paste(regex.escape(words), collapse='|'), ')(?!\\w)')
gsub(regex, "<<\\1>>", examples, perl=TRUE)
# => [1] "Text: cm+km, <<+km>> and <<C++>>,Delphi,C++CLI and <<C++>>/CLI."
# Whitespace boundaries
regex <- paste0('(?<!\\S)(', paste(regex.escape(words), collapse='|'), ')(?!\\S)')
gsub(regex, "<<\\1>>", examples, perl=TRUE)
# => [1] "Text: cm+km, <<+km>> and C++,Delphi,C++CLI and C++/CLI."
于 2020-04-01T08:35:54.947 回答