【问题标题】:How do I deal with special characters like \^$.?*|+()[{ in my regex?如何在我的正则表达式中处理特殊字符,如 \^$.?*|+()[{?
【发布时间】:2021-09-16 18:34:14
【问题描述】:

我想匹配regular expression special character\^$.?*|+()[{。我试过了:

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 ""\["

如何匹配特殊字符?


问题中的一些特殊情况,这些问题已经过时且写得很好,以至于它可以厚颜无耻地关闭为这个重复:
Escaped Periods In R Regular Expressions
How to escape a question mark in R?
escaping pipe ("|") in a regex

【问题讨论】:

    标签: regex r r-faq


    【解决方案1】:

    用双反斜杠转义

    R 将反斜杠视为character constants 的转义值。 (...正则表达式也是如此。因此,在为模式提供字符参数时需要两个反斜杠。第一个实际上不是字符,而是使第二个成为字符。)你可以看到如何使用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: €
    

    延伸阅读:Escaping a backslash with a backslash in R produces 2 backslashes in a string, not 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")
    

    形成一个字符类

    You can also wrap the special characters in square brackets to form a character class.

    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", "[")
    

    【讨论】:

    • 使用cat看反斜杠转义的效果很有启发性。
    • 感谢\\Q\\E 的提示。从来没有注意到它被埋在?base::regex
    • 像魅力一样工作stringr::str_detect("a[b", fixed("["))
    【解决方案2】:

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

    \^$.?*|+()[
    

    正在使用 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

    【讨论】:

      猜你喜欢
      • 2023-02-24
      • 1970-01-01
      相关资源
      最近更新 更多