最近看《JAVA编程思想》看到字符串的部分,在讲正则的时候,提到了一个我之前不知道的概念–数量词,在我看来,它决定了正则的匹配范围。
正则中的数量词有Greedy (贪婪)、Reluctant(懒惰)和Possessive(强占)三种
贪婪型
贪婪型:它首先匹配整个字符串,如果不匹配,就从右端去掉一个字符,再进行匹配,直到找到匹配或把整个字符串去完为止。
Pattern compile = pile("(abc)?");Matcher matcher = compile.matcher("abcabcabcabc");System.out.println("是否匹配:" + matcher.find());System.out.println("匹配结果:" + matcher.group());
结果:
是否匹配:true匹配结果:abc
这个程序用”(abc)?” 去匹配”abcabcabcabc”,因为”?”表示0个或1个,所以匹配结果是“abc”,属于贪婪型。
懒惰(勉强)型
懒惰(勉强)型:与贪婪型逻辑相反,先从最小匹配开始,先从空白开始匹配,若不匹配就加入一个字符,直到找到匹配。 这个类型使用的方法是在最后加上一个“?”字符
Pattern compile = pile("(abc)??");Matcher matcher = compile.matcher("abcabcabcabc");System.out.println("是否匹配:" + matcher.find());System.out.println("匹配结果:" + matcher.group());
结果:
是否匹配:true匹配结果:
这次我们的匹配规则在结尾多加了一个“?”,相当于使用了懒惰(勉强)型,懒惰型发现空白也能做到匹配(因为第一个?代表匹配的结果可以是0个) 所以匹配结果是“”。
强占(占有)型
强占(占有)型:它首先匹配整个字符串,但是跟贪婪型不一样的是,如果没有匹配到,就会放弃匹配。这个类型使用的方法是在最后加上一个“+”字符
Pattern compile = pile("(abc)?+");Matcher matcher = compile.matcher("abcabcabcabc");System.out.println("是否匹配:" + matcher.find());System.out.println("匹配结果:" + matcher.group());
结果:
是否匹配:true匹配结果:abc
这次我们的匹配规则在结尾多加了一个“+”,相当于使用了强占(占有)型,强占型直接拿整个字符串进行匹配,发现可以匹配上, 所以匹配结果是“abc”。
注意事项
在java的regex语法中,我们使用的是matcher.find(),代表部分匹配,正如上面的例子,我们取的都是部分匹配的结果,如果你用如下语法
Pattern compile = pile("(abc)?+");Matcher matcher = compile.matcher("abcabcabcabc");System.out.println("是否匹配:" + matcher.matches());System.out.println("匹配结果:" + matcher.group());
结果便是报错,因为matcher.matches()代表完全匹配,整个字符串必须完全符合匹配规则,数量词在这里不起效果,这里要注意:
是否匹配:falseException in thread "main" java.lang.IllegalStateException: No match foundat java.util.regex.Matcher.group(Matcher.java:536)at java.util.regex.Matcher.group(Matcher.java:496)at JDK.String.regex.Regex_3.main(Regex_3.java:18)
相关的例子可以在我的github上看到:
/lovejj1994/DataStructures