提问人:Corvus 提问时间:2/13/2013 最后编辑:CommunityCorvus 更新时间:2/10/2022 访问量:11732
是否有 R 函数可以转义正则表达式字符的字符串
Is there an R function to escape a string for regex characters
问:
我想构建一个正则表达式来替换一些要搜索的字符串,因此需要先对这些字符串进行转义,然后才能将它们放入正则表达式中,以便如果搜索的字符串包含正则表达式字符,它仍然有效。
有些语言有函数可以为你做到这一点(例如python:https://stackoverflow.com/a/10013356/1900520)。R有这样的功能吗?re.escape
例如(组成函数):
x = "foo[bar]"
y = escape(x) # y should now be "foo\\[bar\\]"
答:
显然,在 Hmisc 包中调用了一个函数。该函数本身对输入值“string”具有以下定义:escapeRegex
gsub("([.|()\\^{}+$*?]|\\[|\\])", "\\\\\\1", string)
我之前的回答:
我不确定是否有内置函数,但您可以制作一个来做您想做的事。这基本上只是创建一个你要替换的值的向量和一个你想用什么替换它们的值的向量,然后循环访问那些进行必要替换的值。
re.escape <- function(strings){
vals <- c("\\\\", "\\[", "\\]", "\\(", "\\)",
"\\{", "\\}", "\\^", "\\$","\\*",
"\\+", "\\?", "\\.", "\\|")
replace.vals <- paste0("\\\\", vals)
for(i in seq_along(vals)){
strings <- gsub(vals[i], replace.vals[i], strings)
}
strings
}
一些输出
> test.strings <- c("What the $^&(){}.*|?", "foo[bar]")
> re.escape(test.strings)
[1] "What the \\$\\^&\\(\\)\\{\\}\\.\\*\\|\\?"
[2] "foo\\[bar\\]"
评论
vals
gsub()
我编写了 Perl 函数的 R 版本:quotemeta
library(stringr)
quotemeta <- function(string) {
str_replace_all(string, "(\\W)", "\\\\\\1")
}
我总是使用正则表达式的perl风格,所以这对我有用。我不知道它是否适用于 R 中的“正常”正则表达式。
编辑:我找到了解释为什么这样做的来源。它位于 perlre 手册页的 Quoting Metacharacters 部分:
这曾经用于一个常见的成语中,用于禁用或引用要用于模式的字符串中正则表达式元字符的特殊含义。只需引用所有非“单词”字符:
$pattern =~ s/(\W)/\\$1/g;
正如你所看到的,上面的R代码是这个相同的替换的直接翻译(在经历了反斜杠地狱之后)。手册页还说(强调我的):
与其他一些正则表达式语言不同,没有非字母数字的反斜杠符号。
这强化了我的观点,即该解决方案仅保证用于PCRE。
评论
quotemeta('\s+')
比函数更简单的方法是@ryanthompson字符串前面加上后缀。请参阅帮助文件。\\Q
\\E
?base::regex
使用 rex 包
这些天来,我用 编写所有正则表达式。对于您的特定示例,完全按照您的要求执行操作:rex
rex
library(rex)
library(assertthat)
x = "foo[bar]"
y = rex(x)
assert_that(y == "foo\\[bar\\]")
但当然,所做的远不止于此。这个问题提到了构建正则表达式,而这正是设计的目的。例如,假设我们想匹配 中的确切字符串,之前或之后都没有:rex
rex
x
x = "foo[bar]"
y = rex(start, x, end)
现在 y 是并且只会匹配 x 中包含的确切字符串。^foo\[bar\]$
根据:?regex
该符号与“word”字符(、扩展的同义词)匹配,并且是其否定 ()。
\w
[[:alnum:]_]
\W
[^[:alnum:]_]
因此,使用捕获组,我们可以检测非单词字符的出现,并使用 -syntax 对其进行转义:(\\W)
\\1
> gsub("(\\W)", "\\\\\\1", "[](){}.|^+$*?\\These are words")
[1] "\\[\\]\\(\\)\\{\\}\\.\\|\\^\\+\\$\\*\\?\\\\These\\ are\\ words"
或者类似地,将 ."([^[:alnum:]_])"
"(\\W)"
评论