我认为两者都是相同的,但实际上我看到了不同之处,请看this question中的这个最小例子:
a<-c("/Cajon_Criolla_20141024","/Linon_20141115_20141130",
"/Cat/LIQUID",
"/c_puertas_20141206_20141107",
"/C_Puertas_3_20141017_20141018",
"/c_puertas_navidad_20141204_20141205")
sub("(.*?)_([0-9]{8})(.*)$","\\2",a)
[1] "20141024" "20141130" "/Cat/LIQUID" "20141107" "20141018"
[6] "20141205"
sub("(.*?)_([0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9])(.*)$","\\2",a)
[1] "20141024" "20141115" "/Cat/LIQUID" "20141206" "20141017"
[6] "20141204"
我错过了什么?或者这是一个错误吗?
答案 0 :(得分:12)
这是TRE库中与贪婪修饰符和捕获组相关的错误。参见:
答案 1 :(得分:4)
设置perl=TRUE
为两个表达式提供相同的答案(如预期):
> sub("(.*?)_([0-9]{8})(.*)$","\\2",a,perl=TRUE)
[1] "20141024" "20141115" "/Cat/LIQUID" "20141206" "20141017" "20141204"
> sub("(.*?)_([0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9])(.*)$","\\2",a,perl=TRUE)
[1] "20141024" "20141115" "/Cat/LIQUID" "20141206" "20141017" "20141204"
答案 2 :(得分:1)
虽然我最初被BrodieG回答说服,但似乎[0-9] n次和[0-9] {n}确实不同,至少对于“tre”正则表达式电机而言。根据{{3}},{}运算符是贪心的,[0-9]不是。
因此,在我的案例中,正确的正则表达应该是:
sub("(.*?)_([0-9]{8}?)(.*)$","\\2",a)
发挥重要作用:
sub("(.*?)_([0-9]{8})(.*)$","\\2",a)
[1] "20141024" "20141130" "/Cat/LIQUID" "20141107" "20141018"
[6] "20141205"
sub("(.*?)_([0-9]{8}?)(.*)$","\\2",a)
[1] "20141024" "20141115" "/Cat/LIQUID" "20141206" "20141017"
[6] "20141204"
甚至
> sub("(.*)_([0-9]{8}?)(.*)$","\\2",a)
[1] "20141024" "20141115" "/Cat/LIQUID" "20141206" "20141017"
[6] "20141204"
解释:1)tre考虑?作为“第一次匹配这个原子时评估下一个原子”。 “。?”总是如此。当一切都匹配时,它会切换到_ [0-9] {8}。当到达第一组6个数字时,如果{}不贪婪(不是?),因为(。)也匹配前8个数字,搜索继续查看是否出现另一个“_ [0- 9] {8}“可以在线上找到。如果满足第二组8个数字,它也会将其记忆为匹配模式,然后它到达行尾,保留最后一个匹配模式,[0-9] {8}与第二个8匹配号。
2)当{}运算符被修改时?搜索在第一次看到8个数字时停止,检查_(。*)是否可以与其余数字匹配。它可以,所以它返回第一组8个数字。
请注意, perl regexp电机的工作方式不同,
1)?在{}没有改变之后:
sub("(.*)_([0-9]{8})","\\2",a,perl=TRUE)
[1] "20141024" "20141130" "/Cat/LIQUID" "20141107" "20141018"
[6] "20141205"
sub("(.*)_([0-9]{8}?)","\\2",a,perl=TRUE)
[1] "20141024" "20141130" "/Cat/LIQUID" "20141107" "20141018"
[6] "20141205"
2)?适用于。*使其停止在第一组8个数字:
sub("(.*?)_([0-9]{8}).*","\\2",a,perl=TRUE)
[1] "20141024" "20141115" "/Cat/LIQUID" "20141206" "20141017"
[6] "20141204"
sub("(.*)_([0-9]{8}).*","\\2",a,perl=TRUE)
[1] "20141024" "20141130" "/Cat/LIQUID" "20141107" "20141018"
[6] "20141205"
从这两个观察结果来看,似乎两个引擎在两个不同的实例中对贪婪的解释不同。我总觉得贪婪概念有点模糊......