Pattern类用于创建一个正则表达式,它的构造方法是私有的,不可以直接创建,但可以通Pattern.complie(String regex)简单工厂方法创建一个正则表达式。
- Pattern.split(CharSequence input) 用于分隔字符串,并返回一个String[]
- Pattern.matcher(String regex,CharSequence input) 用于快速匹配字符串,该方法适合用于只匹配一次,且匹配全部字符串。
- Pattern.matcher(CharSequence input) 返回一个Matcher对象
Pattern类只能做一些简单的匹配操作,要想得到更强更便捷的正则匹配操作,那就需要Pattern与Matcher一起合作。
Matcher类介绍Matcher类提供了对正则表达式的分组支持,以及对正则表达式的多次匹配支持。
Matcher类的构造方法也是私有的,不能随意创建,只能通过Pattern.matcher(CharSequence input)方法得到该类的实例。
Matcher类提供Matcher.matches()、Matcher.lookingAt()、Matcher.find()三个匹配操作方法,它们都返回boolean类型,当匹配到时返回true,没匹配到则返回false。
- matches() 对整个字符串进行匹配,只有整个字符串都匹配了才返回true,匹配不上和部分匹配都返回false
- lookingAt() 对前面的字符串进行匹配,只有匹配到的字符串在最前面才返回true
- find() 对字符串进行匹配,匹配到的字符串可以在任何位置
示例:
public static void main(String[] args) {
Pattern p = Pattern.compile("\\d+");
Matcher m = p.matcher("22aa33");
System.out.println(m.matches());// false,因为aa不能被\d+匹配,导致整个字符串匹配未成功
m = p.matcher("2233");
System.out.println(m.matches());// true,因为\d+匹配到了整个字符串
}
示例:
public static void main(String[] args) {
Pattern p = Pattern.compile("\\d+");
Matcher m = p.matcher("22bb33");
System.out.println(m.find());// true
m = p.matcher("aa2233");
System.out.println(m.find());// true
m = p.matcher("aa2233bb");
System.out.println(m.find());// true
}
当使用matches()、lookingAt()、find()执行匹配操作后,就可以利用以下三个方法得到更详细的信息:
- start():返回匹配到的子字符串的第一个字符在字符串中的索引位置,从0开始
- end():返回匹配到的子字符串的最后一个字符在字符串中的索引位置的下一位置,从0开始
- group():返回匹配到的子字符串
示例:
public static void main(String[] args) {
Pattern p = Pattern.compile("\\d+");
System.out.println("==========find 方法==========");
Matcher m = p.matcher("aaa2233bb");
System.out.println(m.find());// true 匹配2223
System.out.println(m.start());// 3
System.out.println(m.end());// 7 返回的是2223后的索引号
System.out.println(m.group());// 2223
System.out.println("==========lookingAt 方法==========");
m = p.matcher("2233bb");
System.out.println(m.lookingAt()); // true 匹配2223
// 由于lookingAt()只能匹配前面的字符串,所以当使用lookingAt()匹配时,start()方法总是返回0
System.out.println(m.start()); // 0,
System.out.println(m.end()); // 4
System.out.println(m.group()); // 2223
System.out.println("==========matches 方法==========");
m = p.matcher("2233bb");
System.out.println(m.matches()); // false,所以后边的执行会报错
System.out.println(m.start());
System.out.println(m.end());
System.out.println(m.group());
}
Matcher类同时提供了replaceAll() 、replaceFirst()、appendReplacement()、appendTail()四个将匹配子串替换成指定字符串的方法,其中:
- appendReplacement(StringBuffer sb, String replacement) 将当前匹配子串替换为指定字符串,并且将替换后的子串以及其之前到上次匹配子串之后的字符串段添加到一个StringBuffer对象里
- appendTail(StringBuffer sb) 将最后一次匹配工作后剩余的字符串添加到一个StringBuffer对象里。
示例:
public static void main(String[] args) {
// 生成 Pattern 对象并且编译一个简单的正则表达式"cat"
Pattern p = Pattern.compile("cat");
// 用 Pattern 类的 matcher() 方法生成一个 Matcher 对象
String str = "fatcatfatcatha";
Matcher m = p.matcher(str);
StringBuffer sb = new StringBuffer();
while(m.find()){
m.appendReplacement(sb,"dog");
}
m.appendTail(sb);
System.out.println("sb:"+sb); //fatdogfatdogha
}
说明: 上面代码while循环,循环两次,第一次循环之后sb=fatdob
;第二次循环之后sb=fatdogfatdog
,然后跳出循环,执行 m.appendTail(sb);
时将str中剩余的内容 ha追加到sb中,最后sb的值为fatdogfatdogha
public static void main(String[] args) {
String str="Hello World"; //待判断的字符串
String reg=".*or.*"; //判断字符串中是否含有or
System.out.println(str.matches(reg)); //调用的是字符串类的matches()方法
}
示例:通过Matcher类的find和group方法依次从目标字符串中取出特定子串
public static void main(String[] args) {
Matcher matcher = Pattern.compile("\\w+").matcher("good good study day day up");
while (matcher.find()){
System.out.print(matcher.group() + " ★ ");
}
System.out.println();
int i = 0; //从第0个位置开始匹配
while (matcher.find(i)) {
System.out.print(matcher.group() + " ★ ");
i = matcher.end(); //匹配到的最后一个元素的下一个位置
}
i = 3;
System.out.println();
// 查找从第3个字符开始的,长度大于等于5的单词
matcher = Pattern.compile("\\w{3,}").matcher("we love china");
while (matcher.find(i)) {
System.out.println(matcher.group() + " " + matcher.start() + " "
+ matcher.end());
i = matcher.end();
}
}
运行程序,结果如下图所示:
public static void main(String[] args) {
Pattern pattern = Pattern.compile("\\w{3,20}@\\w+\\.(com|org|cn|net|gov)");
Matcher matcher = pattern.matcher("342141@126.com");
if (matcher.matches()) {
System.out.println("是一个合法的邮件地址");
} else {
System.out.println("不是一个合法的邮件地址");
}
}
示例3:验证一组电子邮件
public static void main(String[] args) {
String[] mails = {"lianghecai@126.com", "369950806@qq.com", "zhangsan@gmail.cn", "sth@abc.xx"};
String regex = "\\w{3,20}@\\w+\\.(com|org|cn|net|gov)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = null;
for (String item : mails) {
if (matcher == null) {
matcher = pattern.matcher(item);
} else {
matcher.reset(item);
}
if (matcher.matches()) {
System.out.println(item + "是一个合法的邮件地址");
} else {
System.out.println(item + "不是一个合法的邮件地址");
}
}
}
示例4:判断身份证
要么是15位,要么是18位,最后一位可以为字母,并写程序提出其中的年月日。提示:15位和18位的身份证号码都是从7位到第12位为身份证为日期类型。
public static void main(String[] args) {
String idCard = "130681198112092019";
Pattern p1 = Pattern.compile("(\\d{17}[0-9a-zA-Z]|\\d{14}[0-9a-zA-Z])");
Pattern p2 = Pattern.compile("\\d{6}(\\d{8}).*"); //用于提取出生日字符串
// 用于将生日字符串分解为年月日
Pattern p3 = Pattern.compile("(\\d{4})(\\d{2})(\\d{2})");
Matcher matcher1 = p1.matcher(idCard);
//判断是否符合身份证格式
if (matcher1.matches()) {
//匹配日期部分的字符串
Matcher matcher2 = p2.matcher(idCard);
//提取相匹配的日期字符串
boolean b = matcher2.find();
if (b) {
String s = matcher2.group(1); //取出日期相关的部分
Matcher matcher3 = p3.matcher(s);
if (matcher3.find()) {
System.out.println(idCard + "\t生日为" + matcher3.group(1) + "年" + matcher3.group(2) + "月" + matcher3.group(3) + "日");
}
}
}
}