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不能处理前瞻和后瞻吗?

【问题讨论】:

查看帮助页面regexperl=TRUE 支持 Lookbehind。所以regexp("^\\d4|\\d1(?&lt;=\\d3$)",s) 不会抛出错误,而是不会选择你想要的。 感谢您的提示!我知道正则表达式不会捕获所有内容,我只是在尝试一下 - 当我不断收到“无效的正则表达式”消息时被踩住了。 在 gsubfn 中使用 strapply 时,此正则表达式有效,不需要前瞻或后瞻:L &lt;- 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) 提取的,id2as.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模式与匹配的正则表达式搜索模式分组以作为整体替换

正则表达式的可变长度lookbehind-assertion替代方案

如何测试以确定浏览器是不是支持 JS 正则表达式lookahead/lookbehind?

如何使用带有线锚的 C# 正则表达式 Lookbehind

Javascript 替代品中的正则表达式 Lookbehind