R:有关可变宽度回顾的解决方法

5

考虑这个向量:

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

我希望将每个单词的最后一个字母“a”改成“i”,但是“baa”和“aba”除外。
我编写了以下代码行...
gsub('(?<=a[ab]b{1,2})a','i',ba,perl=T)

但是被告知:PCRE模式编译错误,“回顾断言不是固定长度”在“)a”处。

我查了一下,显然R/Perl只能向前搜索可变宽度,而不能进行向后搜索。有没有解决这个问题的方法?谢谢!

2个回答

7
你可以使用反向断言的替代方案 \K。此转义序列重置报告的匹配起点,并且先前消耗的字符不再包括在内。 引用 - rexegg

\K 和反向断言的关键区别在于,在 PCRE 中,反向断言不允许您使用量词:您要查找的内容的长度必须是固定的。另一方面,\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"

我能问一下在另一个方向上是否有类似于 \\K 的等效物,即重置报告的匹配结束点吗? - dasf
1
是的,如果我理解你的要求的话,\G - hwnd

2

当仅使用限定量词时,当前情况下的另一种解决方案仅限于此,可能是使用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 向后查找中实际上不能使用任何类型的模式,但当您需要获取已知距离范围内的重叠文本时,最好知道您至少可以在其中使用一个限定量词。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接