Excel精英培训网

 找回密码
 注册
数据透视表40+个常用小技巧,让你一次学会!
查看: 3532|回复: 10

[已解决]正则表达式 零宽度负预测先行断言例2

[复制链接]
发表于 2012-11-28 23:24 | 显示全部楼层 |阅读模式
Sub Test()
    With CreateObject("vbscript.regexp")
        .Global = True
        .Pattern = "\d+(?=分)"
        MsgBox .Replace("8时43分21秒至17时9分56秒", "x")
    End With
End Sub



【前者】
此时,是零宽度正预测先行断言(?=exp),没问题。

【后者】
如果改为
  .Pattern = "\d+(?!分)"
那么就是零宽度负预测先行断言(?!exp)。
我以为会返回:"x时43分x秒至x时9分x秒"
实际却是返回:"x时x3分x秒至x时9分x秒"


问1:为什么前者是贪婪,后者是懒惰?
问2:怎样设置正则表达式,可返回"x时43分x秒至x时9分x秒"
谢谢!
最佳答案
2012-11-29 11:24
你首先要匹配到,才能说匹配的多还是少.""43分"",从后往前匹配啊
分不对,再看3,3OK,那就匹配到前面的数值,4
明显匹配到4,比什么都匹配不到来的多.

不是看匹配到的项多少,是匹配到的长度而言的.你的原则是正确的,只是没有想清楚[从左到右的每个项的长度,同时匹配后的字符串不参与继续匹配].
excel精英培训的微信平台,每天都会发送excel学习教程和资料。扫一扫明天就可以收到新教程
发表于 2012-11-29 10:26 | 显示全部楼层
本帖最后由 wcymiss 于 2012-11-29 10:35 编辑

1、仍然是贪婪。原则是“尽可能多的匹配”
2、\d+(?!分|\d),或:\d+(?!\d*分)
回复

使用道具 举报

发表于 2012-11-29 10:37 | 显示全部楼层
以你的PATTERN应该为:
\d+(?![^\d分])"
因为\d也是!分
即第二段43分
匹配了4因为"3"<>分
回复

使用道具 举报

 楼主| 发表于 2012-11-29 10:45 | 显示全部楼层
wcymiss 发表于 2012-11-29 10:26
1、仍然是贪婪。原则是“尽可能多的匹配”
2、\d+(?!分|\d)

谢谢吴姐!


后者小括号外面仍是 \d+ ,那么我们假设现在仍是贪婪。
按贪婪的工作方式,当第2次匹配时,匹配了蓝色3后:

8时4321秒至17时9分56秒




为什么不再多匹配字符串4,这不是和假设矛盾么?贪婪应尽可能多的匹配啊
回复

使用道具 举报

发表于 2012-11-29 11:05 | 显示全部楼层
针对字符串"8时43分21秒至17时9分56秒",
\d+(?!分)匹配到的有:
843分21秒至17时9分56
而你希望匹配到的是:
8时43分21秒至17时9分56
哪种匹配的多,难道还不显而易见么

评分

参与人数 1 +10 金币 +10 收起 理由
爱疯 + 10 + 10 谢谢!

查看全部评分

回复

使用道具 举报

 楼主| 发表于 2012-11-29 11:05 | 显示全部楼层
liuguansky 发表于 2012-11-29 10:37
以你的PATTERN应该为:
\d+(?![^\d分])"
因为\d也是!分

谢谢花花!

吴姐的结果是我希望得到的,即希望返回的是"x时43分x秒至x时9分x秒"
你的解释中“ .... 因为\d也是!分 ....”,这感叹号是什么意思啊?
回复

使用道具 举报

 楼主| 发表于 2012-11-29 11:15 | 显示全部楼层
wcymiss 发表于 2012-11-29 11:05
针对字符串"8时43分21秒至17时9分56秒",
\d+(?!分)匹配到的有:
8时43分21秒至17时9分56秒

原来,这儿多的含义是两种:
吴姐说的多是,匹配数量尽可能多
我理解的多是,匹配项长度尽可能长

对于“贪婪尽可能多的去匹配”中多的含义是什么?不知吴姐能给个帮助么

回复

使用道具 举报

发表于 2012-11-29 11:24 | 显示全部楼层    本楼为最佳答案   
你首先要匹配到,才能说匹配的多还是少.""43分"",从后往前匹配啊
分不对,再看3,3OK,那就匹配到前面的数值,4
明显匹配到4,比什么都匹配不到来的多.

不是看匹配到的项多少,是匹配到的长度而言的.你的原则是正确的,只是没有想清楚[从左到右的每个项的长度,同时匹配后的字符串不参与继续匹配].
回复

使用道具 举报

 楼主| 发表于 2012-11-29 11:31 | 显示全部楼层
\d+(?=分)          只要"分"的前面至少是1位的数,就匹配
\d+(?!分)           只要后面字符不是"分",而这个后面字符的前面至少是1位的数,就匹配

刚才怎么没这么写一下,到此发现自己理解了实际为什么这样返回。






至于多的含义,我认为还是指匹配长度。我修改下查找字符串
Sub Test()
    With CreateObject("vbscript.regexp")
        .Global = True
        .Pattern = "\d+(?!分)"          '希望是"x时43分x秒至x时9分x秒",但不是
        MsgBox .Replace("8时4443分21秒至17时9分56秒", "x")
    End With
End Sub

从这个结果看,匹配了最长的可能,444。


回复

使用道具 举报

 楼主| 发表于 2012-11-29 11:43 | 显示全部楼层
liuguansky 发表于 2012-11-29 11:24
你首先要匹配到,才能说匹配的多还是少.""43分"",从后往前匹配啊
分不对,再看3,3OK,那就匹配到前面的数值,4 ...

谢谢,这个早上刚明白,“贪婪是一口吃完,再一个个吐,。。。。”{:021:}

QQ截图未命名.jpg
图中的1,表示第1次匹配,最早1个。
图中的4,表示第4次匹配
图中的5,表示第5次匹配,最后1个。


点评

先行断言的意思,字面理解就是先判断断言部分嘛.从后往前匹配的.我的理解; 贪婪一直是匹配是多的.而不是"贪婪是一口吃完,再一个个吐",它是针对你匹配到项.你都把贪婪与没有匹配的内容搅在一起了.  发表于 2012-11-29 13:09
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|Excel精英培训 ( 豫ICP备11015029号 )

GMT+8, 2024-4-29 10:10 , Processed in 0.377074 second(s), 18 queries , Gzip On, Yac On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表