【问题标题】:* vs .* in R with regexp* 与 .* 在 R 中使用正则表达式
【发布时间】:2026-01-21 19:15:02
【问题描述】:

为什么 R(至少使用 tidyverse/stringr)可以识别以下正则表达式:*\.(png|jpg|jpeg)? (在R中由于字符转义实际上需要写字符串"*\\.(png|jpg|jpeg)"

我认为正确的正则表达式应该是.*\.(png|jpg|jpeg)(用R写成".*\\.(png|jpg|jpeg)"))

当我介绍第一个表达式时,例如regex101.com,它说这是一个非法的正则表达式。但 R 似乎可以毫无问题地解析它。

为什么?

表达式*\.(png|jpg|jpeg) 是有效的正则表达式吗?如果是这样,为什么 regex101 抱怨?如果不是,为什么 R 接受它?

【问题讨论】:

    标签: r regex


    【解决方案1】:

    如果您将基本 R 正则表达式函数与默认 TRE 正则表达式库一起使用,则模式开头的 * 将被忽略。它符合基于 POSIX 的正则表达式引擎的行为方式,请参阅 this sed demo(此工具在演示中使用 POSIX BRE)。

    作为基于 POSIX 的正则表达式引擎的 TRE 正则表达式引擎会忽略正则表达式开头的 *

    > gsub("*\\.png$", "", "abc.png")
    [1] "abc"
    

    但是,其他 NFA 正则表达式引擎将其视为错误:

    > library(stringr)
    > str_replace("abc.png", "*\\.png$", "")
    Error in stri_replace_first_regex(string, pattern, fix_replacement(replacement),  : 
      Syntax error in regexp pattern. (U_REGEX_RULE_SYNTAX, context=`*\.png$`)
    > gsub("*\\.png$", "", "abc.png", perl=TRUE)
    Error in gsub("*\\.png$", "", "abc.png", perl = TRUE) : 
      invalid regular expression '*\.png$'
    In addition: Warning message:
    In gsub("*\\.png$", "", "abc.png", perl = TRUE) :
      PCRE pattern compilation error
            'quantifier does not follow a repeatable item'
            at '*\.png$'
    

    stringr 正则表达式函数使用ICU regex library,而带有perl=TRUE 的基本R 正则表达式函数使用PCRE regex library不是perl!)

    【讨论】:

    • 这很有用,但同时也很令人困惑......所以带回家的信息:base R 使用 TRE,stringr 使用 ICU,我们可以将 PCRE 与 perl=True 一起使用。
    • 除了我对为什么存在这么多风格的正则表达式感到沮丧之外,还有什么好的资源可以理解 R 如何使用不同的引擎处理不同的正则表达式?和一个比较。谢谢
    • @gota 你知道,gsubfn 默认使用 Tcl 正则表达式引擎。当您尝试在那里使用单词边界时会非常混乱,gsubfn("\\b\\d+(?:,\\d+)*\\b", ~ gsub(",", "", x, fixed=TRUE), "2,000.5MG/ML 2,500.6", backref=0) 不起作用,但 gsubfn("\\y\\d+(?:,\\d+)*\\y", ~ gsub(",", "", x, fixed=TRUE), "2,000.5MG/ML 2,500.6", backref=0) 可以。我知道,没有一个完整的 R 正则表达式资源,抱歉。