正则表达式是一个强大的字符串处理工具,可以对字符串进行查找、提取、分隔、替换等操作。String类里提供了如下几个特殊方法
boolean matches(String regex):判断该字符串是否匹配指定的正则表达式
String replaceAll(String regex, String replacement):将该字符串中所有匹配regex的子串替换成replacement
String replaceFirst(String regex, String replacement):将该字符串中第一个匹配regex的子串替换成replacement
String[] split(String regex):以regex为分隔符,把该字符串分割成多个子串
创建正则表达式
正则表达式是用于匹配字符串的模板,可以匹配一批字符串,所以创建正则表达式就是创建一个特殊的字符串
正则表达式所支持的合法字符
字符 | 解释 |
---|---|
x | 字符x |
0mnn | 八进制数0mnn所表达的字符 |
xhh | 十六进制数0xhh所表达的字符 |
uhhhh | 十六进制数0xhhhh所表达的Unicode字符 |
t | 制表符('u0009) |
n | 新行(换行)符('u000A) |
r | 回车符('u000D) |
f | 换页符('u000C) |
a | 报警(bell)符('u0007) |
e | Escape符('u001B) |
cx | x对应的控制符。cM匹配Ctrl-M,x必须为A~Z或a~z |
正则表达式中的特殊字符
预定义字符
正则表达式中的“通配符”远远超出了普通通配符的功能,被称为预定义字符。
方括号表达式
圆括号表达式
用于将多个表达式组成一个子表达式,圆括号中可以使用或运算符(|)。例如,正则表达式"((public)|(protected)|(prvate))"用于匹配Java的三个访问控制符其中之一
边界匹配符
数量标识符
Greedy(贪婪模式):数量表示符默认采用贪婪模式。贪婪模式的表达式会一直匹配下去,直到无法匹配
Reluctant(勉强模式):用问号后缀(?)表示,只会匹配最少的字符,也称为最小匹配模式
Possessive(占有模式):用加号后缀(+)表示,目前只有Java支持占有模式,通常较少使用
贪婪模式和勉强模式的对比:
String str = "SSR! 大天狗";
//贪婪模式的正则表达式
System.out.println(str.replaceFirst("\\w*","□"));
//勉强模式的正则表达式
System.out.println(str.replaceFirst("\\w*?","□"));
"\w"使用了贪婪模式,数量表示符()会一直匹配下去,所以该字符串前面的所有单词 字符都被它匹配到,直到遇到空格,所以替换后的效果是“□! 大天狗”;如果使用勉强模式,数量表示符(*)会尽量匹配最少字符,即匹配0个字符,所以替换后的结果是“□SSR! 大天狗”。
使用正则表达式
Pattern对象是正则表达式编译后在内存中的表示形式,因此,正则表达式字符串必须先被编译为Pattern对象,然后再利用该Pattern对象创建对应的Matcher对象。执行匹配所涉及的状态保留在Matcher对象中,多个Matcher对象可共享同一个Pattern对象。
典型调用顺序
//将一个字符串编译成Pattern对象
Pattern pattern = Pattern.compile("a*b");
//使用Pattern对象创建Matcher对象
Matcher matcher = pattern.matcher("aaaaab");
boolean b = matcher.matches(); //返回true
上面定义的Pattern对象可以多次重复使用。如果仅需一次使用,则可直接使用Pattern类的静态matches()方法,此方法自动把指定字符串编译成匿名的Pattern对象,并执行匹配
boolean b = pattern.matches("a*b", "aaaaab"); //返回true
上面语句等效于前面的三条语句,但采用这种语句每次都需要重新编译新的Pattern对象,不能重新利用已编译的Pattern对象,所以效率不高
Pattern是不可变类,可供多个并发线程安全使用
Matcher类提供的常用方法:
find():返回目标字符串中是否包含与Pattern匹配的子串
group():返回上一次与Pattern匹配的子串
start():返回上一次与Pattern匹配的子串在目标字符串中的开始位置
end():返回上一次与Pattern匹配的子串在目标字符串中结束位置加1
lookingAt():返回目标字符串前面部分与Pattern是否匹配
matches():返回整个目标字符串与Pattern是否匹配
reset():将现有的Matcher对象应用于一个新的字符序列
CharSequence接口,该接口代表一个字符序列,其中CharBuffer、String、StringBuffer、StringBuilder都是它的实现类。
通过Matcher()类的find()和group()方法从目标字符串中依次取出特定子串(匹配正则表达式的子串)
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class FindGroup
{
public static void main(String[] args)
{
//使用字符串模拟从网络上得到的网页源码
String string = "四洲休闲食品:0754-88117038" +
"清风牌面巾纸:8008282272" + "统一冰红茶:4007000660";
//创建一个Pattern对象,并用它建立一个Matcher对象
//该正则表达式只抓取400X和800X段的电话号码
//实际要抓取哪些电话号码,只要修改正则表达式即可
Matcher matcher = Pattern.compile("((400\\d)|(800\\d))\\d{6}").matcher(string);
//将所有符合正则表达式的子串(电话号码)全部输出
while (matcher.find())
{
System.out.println(matcher.group());
}
}
}
find()方法还可以传入一个int类型的参数,带int参数的find()方法将从该int索引处向下搜索。start()和end()方法主要用于确定子串在目标字符串中的位置
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class StartEnd
{
public static void main(String[] args)
{
//创建一个Pattern对象,并用它建立一个Matcher对象
String regStr = "France LoireAtlantique Bretagne Nantes";
System.out.println("目标字符串是:" + regStr);
Matcher matcher = Pattern.compile("\\w+").matcher(regStr);
while (matcher.find())
{
System.out.println(matcher.group() +
"子串的起始位置:" + matcher.start() +
",其结束位置:" + matcher.end());
}
}
}
目标字符串是:France LoireAtlantique Bretagne Nantes
France子串的起始位置:0,其结束位置:6
LoireAtlantique子串的起始位置:7,其结束位置:22
Bretagne子串的起始位置:23,其结束位置:31
Nantes子串的起始位置:32,其结束位置:38
程序创建一个邮件地址Pattern,再将其与多个邮寄地址进行匹配。当程序中的Matcher为null时,程序调用matcher()方法来创建一个Matcher对象,一旦Matcher对象被创建,程序就调用Matcher的reset()方法将该Matcher应用于新的字符序列
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MatchesTest
{
public static void main(String[] args)
{
String[] mails =
{
"LeBornJames@gmail.com",
"FlashWade@163.com",
"Bosh@yahoo.com"
};
String mailRegEx = "\\w{3,20}@\\w+\\.(com|org|cn|net|gov|ed)";
Pattern mailPattern = Pattern.compile(mailRegEx);
Matcher matcher = null;
for (String mail : mails)
{
if (matcher == null)
{
matcher = mailPattern.matcher(mail);
}
else
{
matcher.reset();
}
String result = mail + (matcher.matches() ? "是":"不是") + "一个有效邮件地址";
System.out.println(result);
}
}
}
Matcher类提供的replaceAll()把字符串中所有与正则表达式的子串替换成:"呵呵"。还提供replaceFirst(),该方法只替换第一匹配的子串。split()方法以空格为分隔符,将字符串分割成多个子串
public class StringReg
{
public static void main(String[] args)
{
String[] msgs =
{
"Java has regular expressions in 1.4",
"regular expressions now expressing in Java",
"Java represses oracular expressions"
};
for (String msg : msgs)
{
System.out.println(msg.replaceFirst("re\\w*" , "哈哈:)"));
System.out.println(Arrays.toString(msg.split(" ")));
}
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。