正则表达式一直被批判不够高效,那我们还需要他?
这个,从存在必合理方面来讲,那就是我们确实需要。当然,我们这里也只是简述一些特性。
一:组(groups)
在表达式 ((A)(B(C))) 中,存在四个这样的组:
1.((A)(B(C))),2.A, 3(B(C)),4(C)
举例:
String input ="ambMcdadbpc"; //也许你看到了下面有些怪异写法,有其他更明了的方式,只是希望大家多了解 String reg = "((a\\w+?)(b\\p{Upper})(c))"; Pattern p = Pattern.compile(reg); Matcher m = p.matcher(input); while(m.find()) { //这里注意,分组是四个组,所以要加"=";m.group(0)=m.group() for(int i=1;i<= m.groupCount();i++) System.out.println("@start:"+m.start(i)+"|@内容:"+m.group(i)+"|@end:"+m.end(i)); }
二:字段摘要
字段 | 作用 | 嵌入式表达式 |
CANON_EQ | 启用规范等价 | |
CASE_INSENSITIVE | 启用不区分大小写的匹配 | (?i) |
COMMENTS | 模式中允许空白和注释。 | (?x) |
DOTALL | 启用 dotall 模式。 | (?s) |
LITERAL | 启用模式的字面值解析。 | |
MULTILINE |
启用多行模式。 | (?m) |
UNICODE_CASE | 启用 Unicode 感知的大小写折叠。 | (?u) |
UNIX_LINES | 启用 Unix 行模式。 | (?d) |
用法举例:
String poem= "Twas brillig, and the slithy toves\n" + "Did gyre and gimble in the wabe.\n"; Matcher m = Pattern.compile("(?m)(\\S+)\\s+((\\S+)\\s+(\\S+))$") .matcher(poem); //Pattern.compile("(\\S+)\\s+((\\S+)\\s+(\\S+))$",Pattern.MULTILINE) // .matcher(poem); while(m.find()) { for(int j = 0; j<= m.groupCount(); j++) println("[" + m.group(j) + "]"); }
解释下:
DOTALL:
在 dotall 模式中,表达式 . 可以匹配任何字符,包括行结束符。默认情况下,此表达式不匹配行结束符。
UNICODE_CASE:
指定此标志后,由 CASE_INSENSITIVE 标志启用时,不区分大小写的匹配将以符合 Unicode Standard 的方式完成。默认情况下,不区分大小写的匹配假定仅匹配 US-ASCII 字符集中的字符
UNIX_LINES:
在此模式中,.、^ 和 $ 的行为中仅识别 '\n' 行结束符。
LITERAL:
指定此标志后,指定模式的输入字符串就会作为字面值字符序列来对待。输入序列中的元字符或转义序列不具有任何特殊意义。 标志 CASE_INSENSITIVE 和 UNICODE_CASE 在与此标志一起使用时将对匹配产生影响。其他标志都变得多余了。
//--需要增加 字面值字符序列的讲解
三。 量词(数量词)
1. 贪婪性(Greedy 数量词)
贪婪表达式会为所有可能的模式发现尽可能多的匹配
X? X,一次或一次也没有
X* X,零次或多次
X+ X,一次或多次
X{n} X,恰好 n 次
X{n,} X,至少 n 次
X{n,m} X,至少 n 次,但是不超过 m 次
2. 勉强型(Reluctant 数量词) 匹配满足模式所需最少字符数
X?? X,一次或一次也没有
X*? X,零次或多次
X+? X,一次或多次
X{n}? X,恰好 n 次
X{n,}? X,至少 n 次
X{n,m}? X,至少 n 次,但是不超过 m 次
3. 占有型(Possessive 数量词)
用于防止回溯,使正则表达式执行起来更有效
X?+ X,一次或一次也没有
X*+ X,零次或多次
X++ X,一次或多次
X{n}+ X,恰好 n 次
X{n,}+ X,至少 n 次
X{n,m}+ X,至少 n 次,但是不超过 m 次
做个简单比较
String input = "abcaBcabcdaa"; Pattern p = Pattern.compile("a++"); //Pattern p = Pattern.compile("a+"); Matcher m = p.matcher(input); while(m.find()) { System.out.println(m.group()); }
四:Scanner 扫描
看下这个类的定义:一个可以使用正则表达式来解析基本类型和字符串的简单文本扫描器。
这个类可以用InputStream,String,Readable等来构造,在扫描输入流时,会起到一定的作用。(注:在读取一个大型文件夹,在各行中选取兴趣内容,是否能得到效率上优势,笔者未曾尝试)。 这个类没有太深入的东西,我会在“速食广场”一栏中再次给出他的一些例子。
五:StringTokenizer (他被遗弃了,忘了他吧!)
依然做个小结:
1. 灵活的运用正则表达式,能让你的代码更加的优雅;
2. 终于有了Scanner.