在 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+ 个字符
您可以使用带有 regexec
和 regmatches
的基数 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
我有如下所示的文本字符串:
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+ 个字符
您可以使用带有 regexec
和 regmatches
的基数 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