首页 新闻 会员 周边

正则表达式关于零宽度的问题

0
悬赏园豆:50 [已解决问题] 解决于 2015-08-24 09:26

看了好多博客中写道零宽度的问题,每次说到如果(?!X)都是一带而过,只会解释和(?=X)是相反的,即后面不能是X,->如果(?!X)放在右边例如(\w+)(?!\.com),表明待捕获字符串后面不能是.com

String s="baidu.com";
        String regularExp="(\\w+)(?!\\.com)";
        Pattern p1=Pattern.compile(regularExp);
        Matcher matcher = p1.matcher(s);
        while(matcher.find()){
            String group=matcher.group();
            System.out.println(group);
        }

我想的是,这个应该是匹配不上的,但是却匹配上了baid,com这两个,求解为什么

net_程序猿的主页 net_程序猿 | 初学一级 | 园豆:157
提问于:2015-08-23 12:13
< >
分享
最佳答案
1

第一个小括号匹配字符串,第二个小括号匹配位置。

由于\w+是贪婪匹配,匹配的字符越多越好。\w不包含点号(.)。

所以while循环匹配了两次:

第一次匹配字符是baid,位置是d和u之间;

第二次匹配字符是com,位置是字符串结尾。

收获园豆:50
ThreeTree | 小虾三级 |园豆:1490 | 2015-08-23 14:07

其实我是想知道既然是贪婪匹配,为什么没有一下子匹配到u的位置,而是只匹配到d 的位置

net_程序猿 | 园豆:157 (初学一级) | 2015-08-23 14:42

@net_程序猿: 如果是u的位置,后面正好是.com,但你写的正则表达式要求是该位置后面不能是.com

ThreeTree | 园豆:1490 (小虾三级) | 2015-08-23 17:00

@ThreeTree: 可能是我的表达不是很清楚,我的意思是这样的,'(\\w+)(?!\\.com)'的意思是字符的后面不能是.com,所以我觉得baidu.com这个就应该是不能匹配的,\w+应该是一直匹配到u,然后他的后面正好是.com ,所以我认为find()应该返回的是false,而他好像知道如果到了u就是匹配不上的,所以就只算到了d,这样按照规则,就是可以匹配的,问,为什么会这样

net_程序猿 | 园豆:157 (初学一级) | 2015-08-23 23:12

@net_程序猿: 因为正则表达式就是尽可能的找到匹配规则的字符串。

在符合贪婪模式的情况下,第一次成功匹配就是baid,然后从u字符开始,发现紧接着的是点(.),不符合正则表达式;于是从点后面的字符c开始匹配,一直匹配到结束,得到com。

想要达到你的效果,应该是^(\w+)(?!\.com)$这样,加上前后的位置。

不过最好是建议写成\.com$,这样如果匹配成功,就说明是以.com为后缀的字符串。否则就不是了。

这样速度会快些。

ThreeTree | 园豆:1490 (小虾三级) | 2015-08-23 23:42
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册