我想构建一个正则表达式代替一些字符串来搜索,所以这些字符串需要在我将它们放入正则表达式之前进行转义,这样如果搜索到的字符串包含正则表达式字符,它仍然有效
某些语言具有为您执行此操作的功能(例如python re.escape
:https://stackoverflow.com/a/10013356/1900520)。 R有这样的功能吗?
例如(补充功能):
x = "foo[bar]"
y = escape(x) # y should now be "foo\\[bar\\]"
答案 0 :(得分:20)
我写了一个Perl的quotemeta
函数的R版本:
library(stringr)
quotemeta <- function(string) {
str_replace_all(string, "(\\W)", "\\\\\\1")
}
我总是使用regexps的perl风格,所以这对我有用。我不知道它是否适用于R中的“正常”正则表达式。
编辑:我找到了解释其原因的来源。它位于Quoting Metacharacters section of the perlre manpage:
这曾经用于一个常见的习惯用法,用于禁用或引用要用于模式的字符串中正则表达式元字符的特殊含义。只需引用所有非“单词”字符:
$pattern =~ s/(\W)/\\$1/g;
正如您所看到的,上面的R代码是这个相同替换的直接翻译(在通过反斜杠地狱之后)。该联机帮助页还说(强调我的):
与其他一些正则表达式语言不同,没有反斜杠符号不是字母数字。
这强化了我的观点,即这个解决方案只能保证PCRE。
答案 1 :(得分:10)
显然在Hmisc包中有一个名为escapeRegex
的函数。函数本身对'string'的输入值有以下定义:
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\\]"
答案 2 :(得分:0)
比@ryanthompson函数更简单的方法是简单地将\\Q
前缀和后缀\\E
前缀到您的字符串中。参见?base:regex
。
答案 3 :(得分:0)
最近,我使用 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 是 ^foo\[bar\]$
并且只会匹配包含在 x 中的确切字符串。