【发布时间】:2018-09-06 11:15:39
【问题描述】:
我想知道如何在R中实现一个条件正则表达式,这个好像PERL可以实现:
?(if)then|else
但是,我无法弄清楚如何在 R 中实现这一点。举个简单的例子,假设我有以下字符串:
c('abcabd', 'abcabe')
我希望正则表达式匹配"bd"(如果存在),否则匹配"bc",然后将其替换为"zz"。因此,我希望上面的字符串是:
c('abcazz', 'azzabe')
我已经尝试过使用sub 和str_replace 这两种方法似乎都不起作用。看来sub中我的语法可能有误:
sub('b(?(?=d)d|c)', 'zz', c('abcabe','abcabd'), perl=TRUE)
[1] "azzabe" "azzabd"
逻辑是“匹配b,如果后面跟着d匹配d,否则匹配c”。使用str_replace,我得到错误:
str_replace(c('abcabe','abcabd'), regex('b(?(?=d)d|c)'), 'zz')
Error in stri_replace_first_regex(string, pattern, fix_replacement(replacement), :
Use of regexp feature that is not yet implemented. (U_REGEX_UNIMPLEMENTED)
我主要使用stringr,因此更喜欢使用str_replace 的解决方案,但也欢迎使用sub 的解决方案。
【问题讨论】:
-
在发布的答案中,我使用了
sub(),您可以将其转换为str_replace:str_replace(c('abcabe','abcabd'), regex('^(.*)bd|bc'), '\\1zz') -
谢谢!我仍在努力理解您发布的条件正则表达式,但关于这个替代方案,这就是正则表达式总是更喜欢贪婪选项的原因,即。什么匹配最长的字符串?
-
Regex 引擎会尝试第一个路径,如果失败则尝试下一个立即可用的路径。在
^(.*)bd中,引擎会遍历所有字符,如果存在bd,则引擎不会尝试交替的另一端(已经找到匹配项,满意),但如果失败则查找bc。这会导致引擎不会错过匹配bd之前的机会bc也是。 -
太好了,我想我现在明白了。我相信正在发生的事情是正则表达式逐个字符地搜索匹配项,使用交替的顺序
|来确定优先级,因此为什么^(.*)bd|bc有效但bd|bc无效。 -
bd|bc这是b[cd]的一种奇特方式(但顺序很重要)使引擎在每个步骤中都有 2 个直接选择。如果接下来的两个字符不是bd,它将尝试bc,并在找到匹配项后立即停止。