在 R 中使用正则表达式提取文本时出错

error while extracting text using regex in R

我有如下所示的文本字符串:

txt = "(2) 1G–1G (0)"

并且,数据框:

DF <- data.frame(txt = c('(2) 1G–1G (0)','(1) 1G–1G (4)','(2) 1G–1G (0)'))

我试图以如下所示的方式提取括号内的数字:

我希望提取的结果采用这种格式:

  2 - 0

我用的是这个:

gsub('.+\(([0-9]+)\) 1G–1G \(([0-9]+)\).*$', '\1 \2', txt)

但是我从上面得到的是:

 "(2) 1G–1G (0)"

不知道哪里错了。 有人可以解释为什么这段代码没有按照我希望的方式工作吗?

您可以使用

DF$txt <- trimws(gsub("[^()–]*\(([0-9]+)\)[^()–]*"," \1 ",DF$txt))
## => [1] "2 – 0" "1 – 4" "2 – 0"

参见regex demo and the R demo online

详情

  • [^()–]* - 除了 ()-
  • 之外的任何 0+ 个字符
  • \( - 一个 (
  • ([0-9]+) - 第 1 组:一个或多个数字
  • \) - 一个 ) 字符
  • [^()–]* - 除了 ()-
  • 之外的任何 0+ 个字符

您可以使用带有 regexecregmatches 的基数 R 提取它们,如下所示:

(df <- data.frame(txt = c('(2) 1G–1G (0)','(1) 1G–1G (4)','(2) 1G–1G (0)', 'somejunkhere')))

getNumbers <- function(col) {
  (result <- sapply(col, function(x) {
      m <- regexec("\((\d+)\)[^()]*\((\d+)\)", x, perl = TRUE)
      groups <- regmatches(x, m)
      (out <- ifelse(identical(groups[[1]], character(0)),
                    NA,
                    sprintf("%s - %s", groups[[1]][2], groups[[1]][3])))
    }))
}
df$extracted <- getNumbers(df$txt)
df

这会产生

            txt extracted
1 (2) 1G–1G (0)     2 - 0
2 (1) 1G–1G (4)     1 - 4
3 (2) 1G–1G (0)     2 - 0
4  somejunkhere      <NA>

不明白为什么会说不行:

sub(".*\((\d+).*\((\d+).*","\1-\2",DF$txt)
 [1] "2-0" "1-4" "2-0"

甚至:

 transform(DF,extracted=sub(".*\((\d+).*\((\d+).*","\1 - \2",txt))
            txt extracted
1 (2) 1G–1G (0)     2 - 0
2 (1) 1G–1G (4)     1 - 4
3 (2) 1G–1G (0)     2 - 0