学习过程中,总是一味的在回避正则表达式,总觉得有点触不可及,现在就来全面的分析理解一下,就当是个复习。
正则表达式定义了字符串的模式。
正则表达式可以用来搜索、编辑或处理文本。
正则表达式并不仅限于某一种语言,但是在每种语言中有细微的差别。Java正则表达式和Perl的是最为相似的。
Java正则表达式的类在 java.util.regex 包中,包括三个类:Pattern,Matcher 和 PatternSyntaxException。
Pattern对象是正则表达式的已编译版本。他没有任何公共构造器,我们通过传递一个正则表达式参数给公共静态方法 compile 来创建一个pattern对象。
Matcher是用来匹配输入字符串和创建的 pattern 对象的正则引擎对象。这个类没有任何公共构造器,我们用patten对象的matcher方法,使用输入字符串作为参数来获得一个Matcher对象。然后使用matches方法,通过返回的布尔值判断输入字符串是否与正则匹配。
如果正则表达式语法不正确将抛出PatternSyntaxException异常。
正则表达式语法总览:
捕获组是把多个字符当一个单独单元进行处理的方法,它通过对括号内的字符分组来创建。
例如,正则表达式(dog) 创建了单一分组,组里包含"d","o",和"g"。
捕获组是通过从左至右计算其开括号来编号。
例如,在表达式((A)(B(C))),有四个这样的组:
((A)(B(C)))、(A)、(B(C))、(C)
可以通过调用matcher对象的groupCount方法来查看表达式有多少个分组。
groupCount方法返回一个int值,表示matcher对象当前有多个捕获组。
还有一个特殊的组(组0),它总是代表整个表达式。该组不包括在groupCount的返回值中。
Matcher类
索引方法提供了有用的索引值,精确表明输入字符串中在哪能找到匹配:
研究方法用来检查输入字符串并返回一个布尔值,表示是否找到该模式:
替换方法是替换输入字符串里文本的方法:
PatternSyntaxException类
PatternSyntaxException 是一个非强制异常类,它指示一个正则表达式模式中的语法错误。
PatternSyntaxException 类提供了下面的方法来帮助我们查看发生了什么错误。
一个例子:
package com.anxpp.demo; import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexExamples { public static void main(String[] args) { //创建一个带有标志的Pattern对象(此处为不区分大小写) Pattern pattern = Pattern.compile("ab", Pattern.CASE_INSENSITIVE); //源字符串 Matcher matcher = pattern.matcher("ABcabdAb"); //使用Matcher find(),group(),start()和 end()方法 while (matcher.find()) { System.out.println("Found the text \"" + matcher.group()+"\" starting at "+matcher.start()+" index and ending at index "+matcher.end()); } //\W表示非英文字母 pattern = Pattern.compile("\\W"); //分割字符串 String[] words = pattern.split("one@two#three:four$five"); //遍历并输出结果 for (String s : words) { System.out.println("Split using Pattern.split(): " + s); } //使用Matcher.replaceFirst()、replaceAll()方法 //*表示零次或多次匹配前面的字符或子表达式 pattern = Pattern.compile("1*2"); //源字符串 matcher = pattern.matcher("11234512678"); //替换全部匹配的字符串为_ System.out.println("Using replaceAll: " + matcher.replaceAll("_")); //替换首个匹配的字符串为_ System.out.println("Using replaceFirst: " + matcher.replaceFirst("_")); //Pattern与String的matches方法 String str = "bbb"; System.out.println("Using String matches method: "+str.matches(".bb")); System.out.println("Using Pattern matches method: "+Pattern.matches(".bb", str)); // 按指定模式在字符串查找(下面的例子说明如何从一个给定的字符串中找到数字串) //源字符串 String line = "This order was placed for QT3000! OK?"; //.*表示任意个任意字符,\d+表示连续至少一个数字 Matcher m = Pattern.compile("(.*)(\\d+)(.*)").matcher(line); if (m.find()) { //分别输出组0到2匹配的字符串 System.out.println("Found value: " + m.group(0)); System.out.println("Found value: " + m.group(1)); System.out.println("Found value: " + m.group(2)); } else { System.out.println("NO MATCH"); } //\w为字母,\d为数字,\1(\num)就是组1的引用,这里意思就是又一个(\w\d)且这个(\w\d)与前面的相同,整个表达式意思就是(\w\d)(\w\d)并且两个(\w\d)内容一样 System.out.println(Pattern.matches("(\\w\\d)\\1", "a2a2")); //true System.out.println(Pattern.matches("(\\w\\d)\\1", "a2b2")); //false //\2就是组2的引用,这里的组2就是(B\\d) System.out.println(Pattern.matches("(AB)(B\\d)\\2\\1", "ABB2B2AB")); //true System.out.println(Pattern.matches("(AB)(B\\d)\\2\\1", "ABB2B3AB")); //false } } /*输出如下: Found the text "AB" starting at 0 index and ending at index 2 Found the text "ab" starting at 3 index and ending at index 5 Found the text "Ab" starting at 6 index and ending at index 8 Split using Pattern.split(): one Split using Pattern.split(): two Split using Pattern.split(): three Split using Pattern.split(): four Split using Pattern.split(): five Using replaceAll: _345_678 Using replaceFirst: _34512678 Using String matches method: true Using Pattern matches method: true Found value: This order was placed for QT3000! OK? Found value: This order was placed for QT300 Found value: 0 true false true false */
例子详细解释:后来整理,直接把解释放到代码注释中去了,请看注释↑。
既然正则表达式总是和字符串有关, Java 1.4对String类进行了扩展,提供了一个matches方法来匹配pattern。在方法内部使用Pattern和Matcher类来处理这些东西,但显然这样减少了代码的行数。 Pattern类同样有matches方法,可以让正则和作为参数输入的字符串匹配,输出布尔值结果。
所以如果你的需要仅仅是检查输入字符串是否和pattern匹配,你可以通过调用String的matches方法省下时间。只有当你需要操作输入字符串或者重用pattern的时候,你才需要使用Pattern和Matches类。
注意由正则定义的pattern是从左至右应用的,一旦一个原字符在一次匹配中使用过了,将不会再次使用。例如,正则“121”只会匹配两次字符串“31212142121″,就像这样“_121____121″。