【问题标题】:R Regex expression with gsubR 正则表达式与 gsub
【发布时间】:2022-01-27 18:23:42
【问题描述】:

我正在使用 gsub 正则表达式来选择表达式的最后一部分

例子:

  • “Bla-text-01” - 我想要 -> “text-01”
  • “名称-xpto-08”-我想要->“xpto-08”
  • “text-text-04” - 我想要 -> “text-04”
  • “new-blaxpto-morexpto-07” - 我想要 -> “morexpto-07”
  • “new-new-new-bla-ready-05” - 我想要 -> “ready-05”

我创建了适用于前 3 个案例的代码,但现在我有一个新的请求也适用于 5 个案例。

gsub(x = match$id,
          pattern =  "(.*?-)(.*)",
          replacement = "\\2")

你能帮帮我吗?

【问题讨论】:

  • 只匹配正则表达式[a-z]+-\\d+$Demo。您可能需要将[a-z] 更改为[a-zA-Z] 或设置不区分大小写标志。将光标悬停在链接处表达式的每个部分上,以获得对其功能的解释。

标签: r regex gsub


【解决方案1】:
x <- c("Bla-text-01",
       "Name-xpto-08", 
       "text-text-04", 
       "new-blaxpto-morexpto-07", 
       "new-new-new-bla-ready-05")

sub("^.*-([^-]*-[^-]*)$", "\\1", x)
## [1] "text-01"     "xpto-08"     "text-04"     "morexpto-07" "ready-05"

【讨论】:

  • 谢谢它的工作。
【解决方案2】:

试试这个正则表达式:

sub(".*-(.*-.*)$", "\\1", x)
## [1] "text-01"     "xpto-08"     "text-04"     "morexpto-07" "ready-05"   

其他方法是:

# 2. use basename/dirname
xx <- gsub("-", "/", x)
paste(basename(dirname(xx)), basename(xx), sep = "-")
## [1] "text-01"     "xpto-08"     "text-04"     "morexpto-07" "ready-05"   

# 3. use scan
f <- function(x) {
  scan(text = x, what = "", sep = "-", quiet = TRUE) |>  
    tail(2) |>
    paste(collapse = "-")
}
sapply(x, f)
##              Bla-text-01             Name-xpto-08             text-text-04 
##                "text-01"                "xpto-08"                "text-04" 
##  new-blaxpto-morexpto-07 new-new-new-bla-ready-05 
##            "morexpto-07"               "ready-05" 

注意

以可重现的形式输入:

x <- c("Bla-text-01", "Name-xpto-08", "text-text-04", "new-blaxpto-morexpto-07", 
"new-new-new-bla-ready-05")

【讨论】:

  • 还不如加上vapply(strsplit(x, "-"), function(x) paste(tail(x, 2L), collapse = "-"), "")...
  • 第二种方式是切刀,但.*-(.*-.*)$ 可能会导致许多回溯步骤较长的字符串。以更明确的方式编写它更安全:(?:[^-]*-)*([^-]*-[^-]*])$。或者更好的pcre风味:^(?&gt;[^-]*-)*([^-]*-[^-]*])$