如何在正则表达式中处理\ ^ $。?* | +()[{等特殊字符?


78

我想匹配一个正则表达式特殊字符\^$.?*|+()[{。我试过了:

x <- "a[b"
grepl("[", x)
## Error: invalid regular expression '[', reason 'Missing ']''

(相当于stringr::str_detect(x, "[")stringi::stri_detect_regex(x, "[")。)

将值加倍以使其无法逸出:

grepl("[[", x)
## Error: invalid regular expression '[[', reason 'Missing ']''

也不使用反斜杠:

grepl("\[", x)
## Error: '\[' is an unrecognized escape in character string starting ""\["

如何匹配特殊字符?


在一些古老而又写得很好的问题中,对此有一些特殊情况,以至于像它的副本一样厚脸皮地关闭:
R正则表达式
中的转义符如何在R中转义问号?
在正则表达式中转义管道(“ |”)

Answers:


110

用双反斜杠转义

R将反斜杠视为字符常量的转义值。(...正则表达式也是如此。因此,为模式提供字符参数时,需要两个反斜杠。第一个实际上不是字符,而是使第二个变成字符。)您可以看到如何使用cat

y <- "double quote: \", tab: \t, newline: \n, unicode point: \u20AC"
print(y)
## [1] "double quote: \", tab: \t, newline: \n, unicode point: €"
cat(y)
## double quote: ", tab:    , newline: 
## , unicode point: €

进一步阅读:在R中使用反斜杠转义一个反斜杠会在字符串中产生2个反斜杠,而不是1

要在正则表达式中使用特殊字符,最简单的方法通常是使用反斜杠对其进行转义,但是如上所述,反斜杠本身需要进行转义。

grepl("\\[", "a[b")
## [1] TRUE

要匹配反斜杠,您需要两次转义,以产生四个反斜杠。

grepl("\\\\", c("a\\b", "a\nb"))
## [1]  TRUE FALSE

rebus软件包包含每个特殊字符的常量,以免您误用斜杠。

library(rebus)
OPEN_BRACKET
## [1] "\\["
BACKSLASH
## [1] "\\\\"

有关更多示例,请参见:

?SpecialCharacters

您的问题可以通过以下方式解决:

library(rebus)
grepl(OPEN_BRACKET, "a[b")

形成角色类

您也可以将特殊字符包装在方括号中以形成字符类

grepl("[?]", "a?b")
## [1] TRUE

其中两个特殊字符在字符类中具有特殊含义:\^

即使在字符类中,反斜杠仍然需要转义。

grepl("[\\\\]", c("a\\b", "a\nb"))
## [1]  TRUE FALSE

仅在插入方括号后方时才需要插入脱字号。

grepl("[ ^]", "a^b")  # matches spaces as well.
## [1] TRUE
grepl("[\\^]", "a^b") 
## [1] TRUE

rebus 还可以让您形成一个角色类。

char_class("?")
## <regex> [?]

使用预先存在的角色类

如果要匹配所有标点符号,则可以使用[:punct:]字符类。

grepl("[[:punct:]]", c("//", "[", "(", "{", "?", "^", "$"))
## [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE

stringi 将其映射到Unicode通用类别进行标点,因此其行为略有不同。

stri_detect_regex(c("//", "[", "(", "{", "?", "^", "$"), "[[:punct:]]")
## [1]  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE

您也可以使用跨平台语法来访问UGC。

stri_detect_regex(c("//", "[", "(", "{", "?", "^", "$"), "\\p{P}")
## [1]  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE

使用\ Q \ E转义

将字符放在\\Q和之间,\\E使正则表达式引擎按字面意义而不是将其视为正则表达式。

grepl("\\Q.\\E", "a.b")
## [1] TRUE

rebus 使您可以编写正则表达式的文字块。

literal(".")
## <regex> \Q.\E

不要使用正则表达式

正则表达式并不总是答案。如果要匹配固定的字符串,则可以这样做,例如:

grepl("[", "a[b", fixed = TRUE)
stringr::str_detect("a[b", fixed("["))
stringi::stri_detect_fixed("a[b", "[")

2
使用cat看反斜杠被照亮逃逸的效果。
山姆·菲克

感谢\\Q\\E小费。没注意到它被埋在里面?base::regex
dnlbrky

像魅力一样工作stringr::str_detect("a[b", fixed("["))
Pablo Casas

1

我认为匹配字符的最简单方法是

\^$.?*|+()[

正在使用R中的字符类。请考虑以下内容,以从数据文件中清除列标题,其中可能包含空格和标点符号:

> library(stringr)
> colnames(order_table) <- str_replace_all(colnames(order_table),"[:punct:]|[:space:]","")

这种方法使我们可以将字符类字符串化以匹配标点字符,以及空格字符,这通常是您必须逃避\\检测的字符。您可以在下面的备忘单中了解有关字符类的?regexp更多信息,也可以键入以查看有关此字符的更多信息。

https://www.rstudio.com/wp-content/uploads/2016/09/RegExCheatsheet.pdf

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.