在R中的正则表达式中查找元素的最佳方法是什么?

时间:2017-12-05 19:26:02

标签: r

我在R中有一个字符串列表,如下所示:

"A(123:456)"
"B(23456:345)"
"C(3451:45600)"

我想解析所有这些项目的括号中的第一个数字和第二个数字:

first   second
123     456
23456   345
3451    45600

以矢量化方式执行此操作的最佳方法是什么?我曾经想过使用子串和索引,但后来听说过正则表达式,但我想知道最多" R"这样做的方法。

3 个答案:

答案 0 :(得分:4)

您可以使用regexpr来匹配模式, 并regmatches提取匹配的模式。

您可以将要匹配(要提取)的模式定义为\\d+,这意味着一个或多个数字。 这将匹配每个模式中出现的前3位数。 并使用regmatches提取匹配项,如下所示:

v <- c("A(123:456)", "B(234:345)", "C(345:456)")
regmatches(v, regexpr('\\d+', v))

上面将给出一个值向量:

[1] "123" "234" "345"

要获得包含两列数值的data.frame, 您可以使用gregmatches代替regmatches。 返回列表列表, 您可以从中将值提取到向量中:

m <- regmatches(v, gregexpr('\\d+', v))
first <- sapply(m, function(x) x[[1]])
second <- sapply(m, function(x) x[[2]])

或者在评论中指出@RuiBarradas,您可以像这样简化sapply次调用:

first <- sapply(m, '[[', 1)
second <- sapply(m, '[[', 2)

答案 1 :(得分:1)

这是正则表达式的一种方式:

# Your data
df <- data.frame(obs=c("A(123:456)","B(234:345)","C(345:456)"))
# extraction:
df$first <- gsub(df$obs,pattern="^.*\\((.*)\\:.*$",replacement="\\1")

答案 2 :(得分:1)

这有两种方式 第一个是最简单的,如果你的字符串总是正好有两个字符后面跟着三位数的兴趣,它就会起作用。
第二个使用正则表达式。

substr(x, 3, 5)
[1] "123" "234" "345"

sub("^.*\\(([[:digit:]]*).*", "\\1", x)
[1] "123" "234" "345"

然后,如果您想要数字结果,请使用as.integeras.numeric

数据。

x <- scan(what = character(), text = '
"A(123:456)"
"B(234:345)"
"C(345:456)"')

修改
在OP编辑问题后,上述解决方案不再有效。以下是。请注意,正则表达式已更改,我现在也使用strsplit

res <- do.call(rbind, strsplit(sub("^.*\\((.*)\\).*$", "\\1", x), ":"))
res <- as.data.frame(res, stringsAsFactors = FALSE)
names(res) <- c("first", "second")
res
#  first second
#1   123    456
#2   234    345
#3   345    456

此数据框的列都是类character。为了得到数字,用

强制它们
res[] <- lapply(res, as.integer)