R中PCRE正则匹配\和[异常问题及解决
R中自定义正则替换非法字符的问题与解决
我在R中尝试用regex自定义替换非法字符,已知base::make.names能实现部分功能,但需要自定义替换字符。已经成功处理Windows文件名非法字符(处理\时需要用sub("\\", "\\\\", .)转义来适配gsub),代码如下:
wdc <- c( "<", ">", ":", '"', "/", "\\", "|", "?", "*" ) %>% magrittr::set_names(., .) wdc_regex <- wdc %>% sub("\\", "\\\\", .) %>% c("[", ., "]") %>% paste0(collapse = "") wdc %>% c(letters[1:5]) %>% gsub(wdc_regex, "_", ., perl = TRUE)
执行上述代码结果正常,但处理R合法命名的非法字符时遇到两个问题:
- 替换
\无需执行转义步骤即可生效,原因是什么?测试显示未转义\时,它仍被替换为_。 - 未在
rdc_regex的字符集中包含[和],但这两个字符仍被替换,原因是什么?
问题1解答
在R的字符串中,\本身是转义字符,所以你定义的原始字符向量里的"\\"实际上在R中存储的是单个\字符。当构建正则字符类[...]时,\在字符类中不需要额外转义(除了在R字符串层面的转义),所以即使你没做额外的转义步骤,正则引擎也能识别这个字符并替换。而之前处理Windows文件名时的转义,是因为在构建正则字符串时需要确保R把\正确传递给正则引擎,但在字符类中\的特殊性质有所不同,因此无需额外转义也能匹配。
问题2解答
这是因为最初构建正则字符类时,没有正确转义字符类中的特殊字符。比如字符列表里的-、^等在正则字符类中有特殊含义:-会被当作范围符(如a-z表示a到z的字符),^如果在字符类开头会变成否定字符类。这些未转义的特殊字符会导致字符类的实际匹配范围被意外扩展,甚至引发语法解析错误,间接导致[和]被错误匹配。
最终通过转义字符类中的特殊字符(-、$、^等)解决了问题,代码如下:
rdc_test <- c( "<", ">", ":", '"', "/", "\\", "|", "?", "*", "~", ",", ";", "+", "-", "`", "!", "@", "#", "$", "%", "^", "&", "=", "(", ")", "'", "{", "}" , "[", "]" ) %>% magrittr::set_names(., .) rdc <- c( "<", ">", ":", '"', "/", "\\", "|", "?", "*", "~", ",", ";", "+", "\\-", "`", "!", "@", "#", "\\$", "%", "\\^", "&", "=", "(", ")", "'", "{", "}" , "[", "\\]" ) rdc_regex <- rdc %>% sub("\\", "\\\\", .) %>% c("[", ., "]") %>% paste0(collapse = "") rdc_test %>% c(letters[1:5]) %>% gsub(rdc_regex, "_", ., perl = TRUE)
内容的提问来源于stack exchange,提问作者Josh
相关产品推荐
相关产品推荐

