[英]Using variable to create regular expression pattern in R
我有一个功能:
ncount <- function(num = NULL) {
toRead <- readLines("abc.txt")
n <- as.character(num)
x <- grep("{"n"} number",toRead,value=TRUE)
}
grep-ing 时,我希望函数中传递的 num 动态创建要搜索的模式? 这如何在 R 中完成? 文本文件的每一行都有数字和文本
您可以使用paste
连接字符串:
grep(paste("{", n, "} number", sep = ""),homicides,value=TRUE)
为了从 R 中的变量构建正则表达式,在当前场景中,您可以简单地使用paste0
将字符串文字与您的变量连接paste0
:
grep(paste0('\\{', n, '} number'), homicides, value=TRUE)
请注意, {
是[...]
括号表达式(也称为字符类)之外的特殊字符,如果您需要查找文字{
char.
如果您使用项目列表作为替代列表,您可以使用paste
/ paste0
的组合:
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
传递给 base R regex 函数时)或 ICU( stringr / stringi regex 函数)已证明可以更好地处理这些情况,建议使用这些引擎而不是 base 中使用的默认 TRE regex 库R 正则表达式函数。
通常,您会希望构建一个包含应该完全匹配的单词列表的模式,作为整个单词。 在这里,很大程度上取决于边界的类型以及单词是否可以包含特殊的正则表达式元字符,它们是否可以包含空格。
在最一般的情况下,单词边界 ( \\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)
,当匹配需要用空白字符或字符串的开头/结尾括起来时 R 中前两种方法的示例(替换为用<<
和>>
括起来的匹配项):
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."
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.