【问题标题】:R: workaround for variable-width lookbehindR:可变宽度后视的解决方法
【发布时间】:2015-06-01 05:36:23
【问题描述】:

给定这个向量:

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

除了baaaba 之外,我想将每个单词的最后a 更改为i

我写了下面这行...

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

但被告知:PCRE 模式编译错误'lookbehind assertion is not fixed length' at ')a'

我环顾了一下,显然 R/Perl 只能向前看,而不是向后看。这个问题的任何解决方法?谢谢!

【问题讨论】:

    标签: regex r lookbehind


    【解决方案1】:

    您可以改用后向替代\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"
    

    【讨论】:

    • 我也可以问一下在另一个方向上是否有\\K的等价物,即重置报告匹配的终点?
    • 是的,\G 如果我按照您的要求进行操作。
    【解决方案2】:

    另一种解决方案仅针对当前情况,当使用的唯一量词是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 后视中使用任何类型的模式,但很高兴知道当您需要在已知距离范围内获取重叠文本时,您至少可以在其中使用限制量词。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-16
      • 2011-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-24
      • 1970-01-01
      相关资源
      最近更新 更多