看了好多博客中写道零宽度的问题,每次说到如果(?!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这两个,求解为什么
第一个小括号匹配字符串,第二个小括号匹配位置。
由于\w+是贪婪匹配,匹配的字符越多越好。\w不包含点号(.)。
所以while循环匹配了两次:
第一次匹配字符是baid,位置是d和u之间;
第二次匹配字符是com,位置是字符串结尾。
其实我是想知道既然是贪婪匹配,为什么没有一下子匹配到u的位置,而是只匹配到d 的位置
@net_程序猿: 如果是u的位置,后面正好是.com,但你写的正则表达式要求是该位置后面不能是.com
@ThreeTree: 可能是我的表达不是很清楚,我的意思是这样的,'(\\w+)(?!\\.com)'的意思是字符的后面不能是.com,所以我觉得baidu.com这个就应该是不能匹配的,\w+应该是一直匹配到u,然后他的后面正好是.com ,所以我认为find()应该返回的是false,而他好像知道如果到了u就是匹配不上的,所以就只算到了d,这样按照规则,就是可以匹配的,问,为什么会这样
@net_程序猿: 因为正则表达式就是尽可能的找到匹配规则的字符串。
在符合贪婪模式的情况下,第一次成功匹配就是baid,然后从u字符开始,发现紧接着的是点(.),不符合正则表达式;于是从点后面的字符c开始匹配,一直匹配到结束,得到com。
想要达到你的效果,应该是^(\w+)(?!\.com)$这样,加上前后的位置。
不过最好是建议写成\.com$,这样如果匹配成功,就说明是以.com为后缀的字符串。否则就不是了。
这样速度会快些。