R vs sed正则表达式贪婪

时间:2013-07-18 15:40:25

标签: regex r sed

我不太明白为什么这不会导致"test",并且会感谢您的解释:

a = "blah test"
sub('^.*(test|$)', '\\1', a)
# [1] ""

将其与sed表达式进行比较:

echo 'blah test' | sed -r 's/^.*(test|$)/\1/'
# test
echo 'blah blah' | sed -r 's/^.*(test|$)/\1/'
#

Fwiw,以下内容实现了我想要的R(并且相当于上述sed结果):

sub('^.*(test)|^.*', '\\1', a)

2 个答案:

答案 0 :(得分:5)

您需要将^.*标记为non-greedy

> sub('^.*?(test|$)', '\\1', "blah test")
[1] "test"
> sub('^.*?(test|$)', '\\1', "blah blah")
[1] ""

答案 1 :(得分:2)

regex engine的开头匹配字符串末尾的所有字符,即贪婪 .*,然后尝试匹配(test|$),即字符串文字'test'或字符串的结尾。由于.*的第一个贪婪匹配与所有字符匹配,因此back-references一个字符,然后再次尝试匹配(test|$),此处$匹配字符串的结尾。

使您的匹配结果为end of line character

我认为sed使用 POSIX NFA ,它会尝试在替代中找到最长匹配,这与R不同,后者似乎使用传统NFA