Regex 是否有R函数来转义正则表达式字符的字符串

Regex 是否有R函数来转义正则表达式字符的字符串,regex,string,r,Regex,String,R,我想构建一个正则表达式来替换一些要搜索的字符串,因此在我将它们放入正则表达式之前,这些字符串需要进行转义,这样,如果搜索的字符串包含正则表达式字符,它仍然可以工作 有些语言有一些函数可以为您实现这一点(例如pythonre.escape:)。R有这样的功能吗 例如(组合功能): 显然,Hmisc包中有一个名为escapeRegex的函数。函数本身对输入值“string”有以下定义: gsub("([.|()\\^{}+$*?]|\\[|\\])", "\\\\\\1", string) 我先前

我想构建一个正则表达式来替换一些要搜索的字符串,因此在我将它们放入正则表达式之前,这些字符串需要进行转义,这样,如果搜索的字符串包含正则表达式字符,它仍然可以工作

有些语言有一些函数可以为您实现这一点(例如python
re.escape
:)。R有这样的功能吗

例如(组合功能):


显然,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
}

re.escape我已经编写了Perl的
quotemeta
函数的R版本:

x = "foo[bar]"
y = escape(x) # y should now be "foo\\[bar\\]"
library(stringr)
quotemeta <- function(string) {
  str_replace_all(string, "(\\W)", "\\\\\\1")
}
正如您所看到的,上面的R代码是这个替换的直接翻译(经过反斜杠地狱之后)。主页还显示(我的重点):

与其他一些正则表达式语言不同,没有非字母数字的反斜杠符号


这强化了我的观点,即该解决方案只保证用于PCRE。

比@ryanthonpson函数更简单的方法是在字符串前面加上
\\Q
和后缀
\\E
。请参阅帮助文件
?base::regex

使用该软件包 现在,我使用
rex
编写所有正则表达式。对于您的特定示例,
rex
正是您想要的:

库(rex)
图书馆(资产)
x=“foo[bar]”
y=rex(x)
断言(y==“foo\\[bar\\]”)
当然,
rex
做的远不止这些。问题涉及到构建正则表达式,而这正是
rex
的设计目的。例如,假设我们想要匹配
x
中的精确字符串,前后都没有任何内容:

x = "foo[bar]"
y = rex(start, x, end)

现在y是
^foo\[bar\]$
,只会匹配x中包含的精确字符串。

您可以添加一个示例字符串以及您希望输出的样子吗?大多数正则表达式函数都有一个名为“fixed”的参数,如果设置为TRUE,将导致模式按原样匹配。这不好-我想构建一个正则表达式,从用户提供的输入-因此我需要“清理”输入,但仍然使用正则表达式。我确信我刚才看到一个好的答案弹出,它消失了…与Dason的答案相关,也请参见stringr::fixed(),这不是一个好的解决方案。您必须在
vals
中包含每个特殊的regexp字符,这可能会变得很困难。@ryanthonpson当然-但这只是一个开始。而且特殊字符的列表是有限的,所以它不是一个非常巨大的负担。我并不是说这是一个最优的解决方案,只是说这是一种可能性。还请注意,您的方法可能会转义通常不被视为正则表达式字符的字符,因此也可能被视为“坏”字符。我的方法可能会转义一些不需要转义的字符,但这样做不会有什么坏处,因为对于PCREs,任何非字母数字字符在前缀为反斜杠时都会被视为文字,即使不需要反斜杠。此方法的另一个致命缺陷是它会连续应用其转义,而不是一次全部应用,因此在一个过程中所做的更改可能会在下一个过程中被篡改。你是对的,我认为它按预期工作。我看得不够仔细,没有注意到反斜杠是列表中的第一个替换字符,而且由于反斜杠也是由
gsub()
添加的唯一字符,因此您永远不会插入字符,然后在插入时执行操作。
$pattern =~ s/(\W)/\\$1/g;
x = "foo[bar]"
y = rex(start, x, end)