目录
Java中与正则表达式相关的类分别为:Pattern 类、Matcher 类和PatternSyntaxException。
三类的功能:pattern 对象是一个正则表达式的编译表示;Matcher 对象是对输入字符串进行解释和匹配操作的引擎;PatternSyntaxException 是一个非强制异常类,它表示一个正则表达式模式中的语法错误。
本文将对这三类常用的基本方法进行简单的介绍。
- Pattern类在java.util.regex 包中 ,且是正则表达式的编译表示形式;
- Pattern类由final修饰,因此不能被子类继承;
- Pattern类的实例不可变,可供多个并发线程安全使用;
- Pattern的构造器是私有的,不能通过new创建Pattern对象,可以通过Pattern调用静态方法compile返回Pattern实例。
1、compile():获取Pattern实例
由于Pattern构造器是私有的,所以不可以通过new创建Pattern对象,可以通过Pattern调用静态方法compile返回Pattern实例。
获取Pattern类的实例有两种方法:
Pattern compile(String regex):
regex正则表达式,该方法是将给定的正则表达式编译并赋予给Pattern类
public static Pattern compile(String regex) { return new Pattern(regex, 0); }
Pattern compile(String regex, int flags):
regex正则表达式,flags控制匹行为的参数,该方法是将给定的正则表达式编译并赋予给Pattern类
public static Pattern compile(String regex, int flags) { return new Pattern(regex, flags); }
关于参数flag,有以下特定值
2、split():拆分字符串
Pattern.split() 将字符串从正则表达式匹配的地方分开
split(CharSequence input)
input 要拆分的字符序列
返回:根据围绕此模式的匹配来拆分输入后所计算的字符串数组
代码实例
String str = "name:'Jack',age:18,sex=M,height:180cm,weight:60kg"; // compile() Pattern p = Pattern.compile("\\d"); // split() String[] arr1 = p.split(str);
Debug
String[] split(CharSequence input, int limit)
input 要拆分的字符序列
limit 结果阈值,控制应用模式的次数,从而影响结果数组的长度
- 若 limit > 0:split最多应用limit - 1次,数组的长度不大于limit,并且数组的最后条目将包含除最后的匹配定界符之外的所有输入;
- 若 limit < 0:split次数不受限制,数组为任意长度;
- 若 limit = 0:split次数不受限制,数组为任意长度,但会摒弃尾部的空字符串;
返回:根据围绕此模式的匹配来拆分输入后所计算的字符串数组
代码实例
String str = "name:'Jack',age:18,sex=M,height:180cm,weight:60kg0000"; // compile() Pattern p = Pattern.compile("\\d"); // split() String[] arr2 = p.split(str, -1); String[] arr3 = p.split(str, 2); String[] arr4 = p.split(str, 5); String[] arr5 = p.split(str, 0);
Debug
- arr2中,limit = -1 < 0,数组长度无限制,即数组长度为12,其中包含几个空字符串
- arr3中,limit = 2 > 0,split()最多使用1次,即数组长度最长为2
- arr4中,limit = 5 > 0,split()最多使用4次,即数组长度最长为5
- arr5中,limit = 0 == 0,split无限制,即数组长度无限制,但会摒弃尾部空字符串
arr2
arr4
arr5
3、matcher():匹配字符串或者返回Matcher实例
Pattern.matcher():或返回一个Matcher实例;
Pattern.matcher():对整个字符串进行匹配,若整个字符串都匹配,返回true;
Pattern.matcher(String regex,CharSequence input)
regex 正则表达式
input 待匹配的字符串
代码实例
// matcher() System.out.println(Pattern.matches("\\d+", "123456")); // true System.out.println(Pattern.matches("\\d+", "aa123456")); // false,需要匹配到所有字符串才能返回true,这里aa不能匹配到
输出结果
- Matcher类在java.util.regex 包中 ,表示执行各种匹配操作的引擎;
- Matcher类由final修饰,因此不能被子类继承;
- Matcher类实例用于多个并发线程不安全;
- 该类没有构造函数,可以使用matches()java.util.regex.Pattern类的方法创建/获取该类的对象。
Matcher 对象是对输入字符串进行解释和匹配操作的引擎,与Pattern 类一样,Matcher 也没有公共构造方法;
1、查找方法
代码实例
// find(): 对字符串进行匹配,匹配到的字符串可以在任何位置, 若匹配到, 返回true, 否则, false
String str1 = "I love Java, Python, Java Java and Java!";
Pattern p1 = Pattern.compile("\\bJava\\b");
Pattern p2 = Pattern.compile("\\d");
Matcher m1 = p1.matcher(str1);
Matcher m2 = p2.matcher(str1);
System.out.println(m1.find()); // true, 字符串中有"Java", 因此返回true
System.out.println(m2.find()); // false, 字符串中没有数字, 因此返回false
// lookingAt(): 对前面的字符串进行匹配,只有匹配到的字符串在最前面,返回true,否则,false
String str3 = "123456";
String str4 = "abc123456";
Pattern p3 = Pattern.compile("\\d+");
Matcher m3 = p3.matcher(str3);
Matcher m4 = p3.matcher(str4);
System.out.println(m3.lookingAt()); // true, 字符串开头是数字
System.out.println(m4.lookingAt()); // false, 字符串开头不是数字
// matches(): 对整个字符串进行匹配,若整个字符串都匹配,返回true,否则,false
System.out.println(m3.matches()); // true, 全部是数字
System.out.println(m4.matches()); // false, 字符串开头不是数字
2、索引方法
代码实例1
// start(): 返回匹配到的子字符串的第一个字符在原字符串中的索引位置
// end(): 返回匹配到的子字符串的最后一个字符在原字符串中的索引位置
// group(): 返回匹配到的子字符串
String str5 = "aa12cc3456bb";
Pattern p5 = Pattern.compile("\\d+");
Matcher m5 = p5.matcher(str5);
while (m5.find()){
System.out.println("匹配到的子字符串group(): " + m5.group()); // 12, 3456
System.out.println("匹配到的子字符串第一个字符索引start(): " + m5.start()); // 2, 6 第一个子字符串的第一个字符索引:2, 第二个子字符串的第一个字符索引:6
System.out.println("匹配到的子字符串最后一个字符索引end(): " + m5.end()); // 4, 10 第一个子字符串的最后一个字符索引:4, 第二个子字符串的最后一个字符索引:10
}
输出结果1
代码实例2
// start(int i): 匹配到的子字符串第i组第一个字符索引
// end(int i): 匹配到的子字符串第i组最后一个字符索引
// group(int i): 匹配到的子字符串的第i组
// groupCount(): 返回分组的数量
String str6 = "aa12cc3456bb";
Pattern p6 = Pattern.compile("([a-z]+)(\\d+)"); // 字母 + 数字
Matcher m6 = p6.matcher(str6);
System.out.println("正则表达式的分组共" + m6.groupCount() + "组");
while (m6.find()){
System.out.println("匹配到的子字符串group(): " + m6.group()); // aa12, cc3456
System.out.println("匹配到的子字符串的第一组group(1): " + m6.group(1)); // aa, cc
System.out.println("匹配到的子字符串的第二组group(2): " + m6.group(2)); // 12, 3456
System.out.println("匹配到的子字符串第一组第一个字符索引start(1): " + m6.start(1)); // aa12中第一组为aa, 索引:0 cc3456中第一组为cc, 索引:4
System.out.println("匹配到的子字符串第二组第一个字符索引start(2): " + m6.start(2)); // aa12中第一组为12, 索引:2 cc3456中第二组为3456, 索引:6
System.out.println("匹配到的子字符串第一组最后一个字符索引end(1): " + m6.end(1)); // aa12中第一组为aa, 索引:2 cc3456中第一组为cc, 索引:6
System.out.println("匹配到的子字符串第二组最后一个字符索引end(2): " + m6.end(2)); // aa12中第一组为12, 索引:4 cc3456中第二组为3456, 索引:10
}
输出结果2
3、替换方法
代码实例1
String str7 = "I love Java、java(Java) and Python!";
Pattern p7 = Pattern.compile("\\bJava\\b");
Matcher m7 = p7.matcher(str7);
// replaceAll(String regex, String replacement):用replacement替换所有的regex匹配项,regex是正则表达式,replacement是字符串
System.out.println("replaceAll(): " + m7.replaceAll("C++")); // I love C++、java(C++) and Python!
// replaceFirst(String regex, String replacement):基本和replaceAll相同,区别是只替换第一个匹配项
System.out.println("replaceFirst(): " + m7.replaceFirst("C++")); // I love C++、java(Java) and Python!
// replace(CharSequence target, CharSequence replacement):用replacement替换所有的target,两个参数都是字符串
System.out.println("replace(): " + "I love Java、java(Java) and Python!".replaceAll("Java", "C++")); // I love C++、java(C++) and Python!
输出结果1
代码实例2
// appendReplacement(): 实现非终端添加和替换步骤
// appendTail():实现终端添加和替换步骤
String str8 = "aabfooaabfooabfoobkkk";
Pattern p8 = Pattern.compile("a*b");
Matcher m8 = p8.matcher(str8);
StringBuffer sb = new StringBuffer();
while (m8.find()){
m8.appendReplacement(sb, "*");
}
System.out.println("appendReplacement(): " + sb.toString()); // *foo*foo*foo*
m8.appendTail(sb);
System.out.println("appendTail(): "+ sb.toString()); // *foo*foo*foo*kkk
输出结果2
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Day12 {
public static void main(String[] args) {
/* Pattern */
String str = "name:'Jack',age:18,sex=M,height:180cm,weight:60kg0000";
// compile()
Pattern p = Pattern.compile("\\d");
// split()
String[] arr1 = p.split(str);
String[] arr2 = p.split(str, -1);
String[] arr3 = p.split(str, 2);
String[] arr4 = p.split(str, 5);
String[] arr5 = p.split(str, 0);
// matcher()
System.out.println(Pattern.matches("\\d+", "123456")); // true
System.out.println(Pattern.matches("\\d+", "aa123456")); // false,需要匹配到所有字符串才能返回true,这里aa不能匹配到
/* Matcher */
// find(): 对字符串进行匹配,匹配到的字符串可以在任何位置, 若匹配到, 返回true, 否则, false
String str1 = "I love Java, Python, Java Java and Java!";
Pattern p1 = Pattern.compile("\\bJava\\b");
Pattern p2 = Pattern.compile("\\d");
Matcher m1 = p1.matcher(str1);
Matcher m2 = p2.matcher(str1);
System.out.println(m1.find()); // true, 字符串中有"Java", 因此返回true
System.out.println(m2.find()); // false, 字符串中没有数字, 因此返回false
// lookingAt(): 对前面的字符串进行匹配,只有匹配到的字符串在最前面,返回true,否则,false
String str3 = "123456";
String str4 = "abc123456";
Pattern p3 = Pattern.compile("\\d+");
Matcher m3 = p3.matcher(str3);
Matcher m4 = p3.matcher(str4);
System.out.println(m3.lookingAt()); // true, 字符串开头是数字
System.out.println(m4.lookingAt()); // false, 字符串开头不是数字
// matches(): 对整个字符串进行匹配,若整个字符串都匹配,返回true,否则,false
System.out.println(m3.matches()); // true, 全部是数字
System.out.println(m4.matches()); // false, 字符串开头不是数字
// start(): 返回匹配到的子字符串的第一个字符在原字符串中的索引位置
// end(): 返回匹配到的子字符串的最后一个字符在原字符串中的索引位置
// group(): 返回匹配到的子字符串
String str5 = "aa12cc3456bb";
Pattern p5 = Pattern.compile("\\d+");
Matcher m5 = p5.matcher(str5);
while (m5.find()){
System.out.println("匹配到的子字符串group(): " + m5.group()); // 12, 3456
System.out.println("匹配到的子字符串第一个字符索引start(): " + m5.start()); // 2, 6 第一个子字符串的第一个字符索引:2, 第二个子字符串的第一个字符索引:6
System.out.println("匹配到的子字符串最后一个字符索引end(): " + m5.end()); // 4, 10 第一个子字符串的最后一个字符索引:4, 第二个子字符串的最后一个字符索引:10
}
// start(int i): 匹配到的子字符串第i组第一个字符索引
// end(int i): 匹配到的子字符串第i组最后一个字符索引
// group(int i): 匹配到的子字符串的第i组
// groupCount(): 返回分组的数量
String str6 = "aa12cc3456bb";
Pattern p6 = Pattern.compile("([a-z]+)(\\d+)"); // 字母 + 数字
Matcher m6 = p6.matcher(str6);
System.out.println("正则表达式的分组共" + m6.groupCount() + "组");
while (m6.find()){
System.out.println("匹配到的子字符串group(): " + m6.group()); // aa12, cc3456
System.out.println("匹配到的子字符串的第一组group(1): " + m6.group(1)); // aa, cc
System.out.println("匹配到的子字符串的第二组group(2): " + m6.group(2)); // 12, 3456
System.out.println("匹配到的子字符串第一组第一个字符索引start(1): " + m6.start(1)); // aa12中第一组为aa, 索引:0 cc3456中第一组为cc, 索引:4
System.out.println("匹配到的子字符串第二组第一个字符索引start(2): " + m6.start(2)); // aa12中第一组为12, 索引:2 cc3456中第二组为3456, 索引:6
System.out.println("匹配到的子字符串第一组最后一个字符索引end(1): " + m6.end(1)); // aa12中第一组为aa, 索引:2 cc3456中第一组为cc, 索引:6
System.out.println("匹配到的子字符串第二组最后一个字符索引end(2): " + m6.end(2)); // aa12中第一组为12, 索引:4 cc3456中第二组为3456, 索引:10
}
String str7 = "I love Java、java(Java) and Python!";
Pattern p7 = Pattern.compile("\\bJava\\b");
Matcher m7 = p7.matcher(str7);
// replaceAll(String regex, String replacement):用replacement替换所有的regex匹配项,regex是正则表达式,replacement是字符串
System.out.println("replaceAll(): " + m7.replaceAll("C++")); // I love C++、java(C++) and Python!
// replaceFirst(String regex, String replacement):基本和replaceAll相同,区别是只替换第一个匹配项
System.out.println("replaceFirst(): " + m7.replaceFirst("C++")); // I love C++、java(Java) and Python!
// replace(CharSequence target, CharSequence replacement):用replacement替换所有的target,两个参数都是字符串
System.out.println("replace(): " + "I love Java、java(Java) and Python!".replaceAll("Java", "C++")); // I love C++、java(C++) and Python!
// appendReplacement(): 实现非终端添加和替换步骤
// appendTail():实现终端添加和替换步骤
String str8 = "aabfooaabfooabfoobkkk";
Pattern p8 = Pattern.compile("a*b");
Matcher m8 = p8.matcher(str8);
StringBuffer sb = new StringBuffer();
while (m8.find()){
m8.appendReplacement(sb, "*");
}
System.out.println("appendReplacement(): " + sb.toString()); // *foo*foo*foo*
m8.appendTail(sb);
System.out.println("appendTail(): "+ sb.toString()); // *foo*foo*foo*kkk
}
}