R 正则表达式 Lookbehind
Posted
技术标签:
【中文标题】R 正则表达式 Lookbehind【英文标题】:R Regular Expression Lookbehind 【发布时间】:2012-02-08 17:30:55 【问题描述】:我有一个用以下格式的字符串填充的向量:<year1><year2><id1><id2>
向量的第一个条目如下所示:
199719982001
199719982002
199719982003
199719982003
对于第一个条目,我们有:year1 = 1997, year2 = 1998, id1 = 2, id2 = 001。
我想写一个正则表达式来提取year1、id1和id2的不为零的数字。所以对于第一个条目,正则表达式应该输出:199721。
我已尝试使用 stringr 包执行此操作,并创建了以下正则表达式:
"^\\d4|\\d1(?<=\\d3$)"
要提取 year1 和 id1,但是当使用后向显示时,我得到一个“无效的正则表达式”错误。这让我有点不解,R不能处理前瞻和后瞻吗?
【问题讨论】:
查看帮助页面regex
。 perl=TRUE
支持 Lookbehind。所以regexp("^\\d4|\\d1(?<=\\d3$)",s)
不会抛出错误,而是不会选择你想要的。
感谢您的提示!我知道正则表达式不会捕获所有内容,我只是在尝试一下 - 当我不断收到“无效的正则表达式”消息时被踩住了。
在 gsubfn 中使用 strapply
时,此正则表达式有效,不需要前瞻或后瞻:L <- c("199719982001", "199719982002", "199719982003", "199719982003"); library(gsubfn); strapply(L, "^(....)....(.)0*(.*)", c, simplify = TRUE)
【参考方案1】:
您需要使用base
包中的gregexpr
。这有效:
> s <- "199719982001"
> gregexpr("^\\d4|\\d1(?<=\\d3$)",s,perl=TRUE)
[[1]]
[1] 1 12
attr(,"match.length")
[1] 4 1
attr(,"useBytes")
[1] TRUE
注意perl=TRUE
设置。有关更多详细信息,请查看?regex
。
从输出来看,你的正则表达式并没有捕捉到id1
。
【讨论】:
【参考方案2】:既然这是固定格式,为什么不使用 substr 呢? year1
是使用 substr(s,1,4)
提取的,id1
是使用 substr(s,9,9)
提取的,id2
是 as.numeric(substr(s,10,13))
。在最后一种情况下,我使用as.numeric
去除零。
【讨论】:
感谢 mpiktas,应该想到这一点。然而,我仍然很好奇为什么后视不起作用......【参考方案3】:你可以使用子。
sub("^(.4).4(.1).*([1-9]1,3)$","\\1\\2\\3",s)
【讨论】:
以上是关于R 正则表达式 Lookbehind的主要内容,如果未能解决你的问题,请参考以下文章
将lookbehind模式与匹配的正则表达式搜索模式分组以作为整体替换
正则表达式的可变长度lookbehind-assertion替代方案