R:可变宽度lookbehind的解决方法

时间:2015-03-27 19:04:16

标签: regex r lookbehind

鉴于此向量:

ba <- c('baa','aba','abba','abbba','aaba','aabba')'

除了ai之外,我想将每个单词的最终baa更改为aba

我写了以下这一行......

gsub('(?<=a[ab]b{1,2})a','i',ba,perl=T)

但被告知: PCRE模式编译错误&#39; lookbehind断言不是固定长度&#39;在&#39;)&#39;

我环顾四周,显然R / Perl只能预测可变宽度,而不是后视。这个问题的解决方法是什么?谢谢!

3 个答案:

答案 0 :(得分:3)

您可以使用lookbehind替代\K。此转义序列重置报告的匹配的起始点,并且不再包括任何以前消耗的字符。

引用 - rexegg

  

\ K和lookbehind之间的主要区别在于,在PCRE中,lookbehind不允许您使用量词:您查找的长度必须是固定的。另一方面,\ K可以放在模式中的任何位置,因此您可以在\ K之前随意拥有任何量词。

在上下文中使用它:

sub('a[ab]b{1,2}\\Ka', 'i', ba, perl=T)
# [1] "baa"   "aba"   "abbi"  "abbbi" "aabi"  "aabbi"

避免外观:

sub('(a[ab]b{1,2})a', '\\1i', ba)
# [1] "baa"   "aba"   "abbi"  "abbbi" "aabi"  "aabbi"

答案 1 :(得分:0)

仅针对当前情况的另一种解决方案,当使用的唯一量词是limiting quantifier时,可能正在使用stringr::str_replace_all / stringr::str_replace

> library(stringr)
> str_replace_all(ba, '(?<=a[ab]b{1,2})a', 'i')
[1] "baa"   "aba"   "abbi"  "abbbi" "aabi"  "aabbi"

它之所以有效,是因为stringr的正则表达式函数基于ICU regex,该函数以限制宽度为特征:

  

与后视模式匹配的可能字符串的长度不能无限制(没有*+运算符。)

因此,您实际上不能在ICU后视中使用任何类型的模式,但是很高兴知道当您需要在已知距离范围内获取重叠文本时,可以至少在其中使用限制量词。

答案 2 :(得分:-1)

"(?!baa|aba)([ab]*)a|" , "\1i"