Regex R vs sed正则表达式贪婪
我不太明白为什么这不会导致Regex R vs sed正则表达式贪婪,regex,r,sed,Regex,R,Sed,我不太明白为什么这不会导致“测试”,希望您能解释一下: 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中想要的结果(相当于上面的sedresults): 您需要将^.*标记为
“测试”
,希望您能解释一下:
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
results):
您需要将
^.*
标记为
regex引擎的开头将匹配字符串末尾的所有字符,即贪婪*
,然后它尝试匹配(test |$)
,即字符串文字“test”或字符串的结尾。由于*
的第一个贪婪匹配匹配匹配了所有字符,它反向引用了一个字符,然后再次尝试匹配(test |$)
,这里$
匹配字符串的结尾
使您的匹配结果成为行尾字符
我认为sed
使用了POSIX-NFA,它试图在替换中找到最长的匹配,这与R
不同,后者似乎使用了传统的NFA@agstudy我正在尝试匹配测试
或行尾-正如你所见sed
理解这一逻辑。我不明白你为什么说(test |$)==$
?我添加了一个编辑,其中包含我想要的内容。@agstudy为了强调我不理解您编写的内容,请尝试运行sub('(test |$),'bb',a)
,其中R当然不会将其解释为与sub('$,'bb',a)
相同,尽管这不会改变结果,但需要注意的是R使用扩展正则表达式和sed(Ubuntu 12.04 64位上的4.2.1)默认使用基本正则表达式。正如我所说,echo'blah test'| sed-r's/^.*(test |$)/\1/')
产生相同的输出。@JoshuaUlrich谢谢,changed@JoshuaUlrich,我不知道我的意思。也许我的意思是懒惰。@GSee是的,你让*
懒惰
@GSee谢谢,这当然很有用,看起来sed
对懒惰/贪婪有不同的理解,因为你链接中的例子对sed
来说是贪婪的:echo“bbb ccc”| sed的//removed/“
导致bbb被删除
;我猜条件句的贪婪有不同的实现方式。有没有一种感觉,其中一个是“正确的”,而另一个不是?从这个链接中,我得到的印象是sed
做错了吗?在这个上下文中,懒惰、不贪婪和不情愿都是同一个意思。但是可选的不适用,所以我删除了它;我是否误解了smth关于传统与POSIX NFA的对比,因为据我所知,(set | setvalue)
和(setvalue | set)
在sed
和R
中的匹配方式完全相同(在“setvalue”上进行匹配测试)…?尽管两者似乎都使用NFA,但它们的实现可能略有不同,在某些情况下,证明一个比另一个快。也读
sub('^.*(test)|^.*', '\\1', a)
> sub('^.*?(test|$)', '\\1', "blah test")
[1] "test"
> sub('^.*?(test|$)', '\\1', "blah blah")
[1] ""