Java-正则表达式-基础

工作中有一段时间经常使用Java的正则表达式,整理一下,做个总结。
JDK中提供了2个类来支持正则表达式,分别是java.util.regex.Pattern和java.util.regex.Matcher。前者表示一个模式,后者表示一个匹配器。
我们在日常使用中,一般会根据需要,建立一个模式。模式的构建通过下面方法:

public static Pattern compile(String regex) {
return new Pattern(regex, 0);
}

或者

public static Pattern compile(String regex, int flags) {
return new Pattern(regex, flags);
}

构建模式时,我们需要传入一个表达式和Match Flags(如果需要的话)。然后便可以得到一个根据传入的字符串型正则表达式而生成的模式实例。可以用这个实例来匹配一些字符串,调用如下方法:

public Matcher matcher(CharSequence input)

此方法返回一个匹配器,接着调用匹配器的相关方法便可判断目标字符串是否匹配我们构建的模式。方法如下:

public boolean matches()

举个简单的例子,现在要判断一个字符串是否是一个以186开头,一共11位的手机号码:

public static void main(String[] args) {
//目标字符串
String s = "18612345678";
//创建匹配模式
Pattern pattern = Pattern.compile("^186\\d{8}$");
//得到匹配器
Matcher matcher = pattern.matcher(s);
//打印匹配结果
System.out.println("isMatch="+matcher.matches());
}

输出为:
isMatch=true

[i]符号'^'表示一行的开始;'\\d'表示数字,这里两个'\'是因为反斜杠在java的字符串中需要转义;'{8}'跟在'\\{d}'后面表示有8个这样的数字;'$'表示一行的结束[/i]

下面是一些常用正则表达式的字符集、运算符、匹配符等。
[table]
|\xhh |16进制值0xhh 所表示的字符
|\uhhhh |16进制值0xhhhh 所表示的Unicode字符
|\t |Tab
|\n |换行符
|\r |回车符
|\f |换页符
|\e |Escape
|. |表示任意一个字符
|[abc] |表示字符a ,b ,c 中的任意一个
|[^abc] |除a ,b ,c 之外的任意一个字符
|[a-zA-Z]| 从a 到z 或A 到Z 当中的任意一个字符
|[abc[hij]]| a,b,c,h,i,j 中的任意一个字符
|[a-z&&[hij]]| h,i,j 中的一个
|\s |空格字符(空格键, tab, 换行, 换页, 回车)
|\S |非空格字符([^\s] )
|\d |一个数字,也就是[0-9]
|\D |一个非数字的字符,也就是[^0-9]
|\w |一个单词字符(word character),即[a-zA-Z_0-9]
|\W |一个非单词的字符,[^\w]
|XY |X 后面跟着 Y
|X|Y |X或Y
|(X) |一个"要匹配的组(capturing group)". 以后可以用\i来表示第i个被匹配的组
|^ |一行的开始
|$ |一行的结尾
|\b |一个单词的边界
|\B |一个非单词的边界
|\G |前一个匹配的结束
|X? |匹配一个或零个X
|X* |匹配零或多个X
|X+ |匹配一个或多个X
|X{n} |匹配正好n个X
|X{n,} |匹配至少n个X
|X{n,m} |匹配至少n个,至多m个X
[/table]

我们可以匹配一个比较长的字符串。

public static void main(String[] args) {
//目标字符串
String input = "127.0.0.1 - - [22/May/2013:23:33:45 +0800] \"GET / HTTP/1.1\" 200 7446";
//创建匹配模式
Pattern pattern = Pattern.compile("^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\s+\\S+\\s+\\S+\\s+\\[[^\\]]+\\]\\s+\"\\S+\\s+/\\s+[^\"]+\"\\s+\\d+\\s+\\d+$");
//得到匹配器
Matcher matcher = pattern.matcher(input);
//打印匹配结果
System.out.println("isMatch="+matcher.matches());
}

输出为:
isMatch=true

观察上面例子的目标字符串(实际上是tomcat的访问日志,这里的正则表达式并不严格,只是做一个简单示范),我们有时可能想要从这些字符串中把一些敏感信息取出来,比如上面目标字符串中的‘IP地址’、‘时间部分’、‘请求方法’、‘协议部分’、‘状态码’。我就需要在表达式中加入捕获式‘()’,然后通过Matcher的API将这些部分取出来,代码如下:

public static void main(String[] args) {
//目标字符串
String input = "127.0.0.1 - - [22/May/2013:23:33:45 +0800] \"GET / HTTP/1.1\" 200 7446";
//创建匹配模式
Pattern pattern = Pattern.compile("^(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})\\s+\\S+\\s+\\S+\\s+\\[([^\\]]+)\\]\\s+\"(\\S+)\\s+/\\s+([^\"]+)\"\\s+(\\d+)\\s+\\d+$");
//得到匹配器
Matcher matcher = pattern.matcher(input);

if(matcher.find()){
for(int i=1;i<=matcher.groupCount();i++){
System.out.println("第"+i+"个捕获的内容为:"+matcher.group(i));
}
}
}

输出为:

第1个捕获的内容为:127.0.0.1
第2个捕获的内容为:22/May/2013:23:33:45 +0800
第3个捕获的内容为:GET
第4个捕获的内容为:HTTP/1.1
第5个捕获的内容为:200

[color=red]注意:[/color]matcher的第一个组"matcher.group(0)"为input本身。

另外,我们可以在正则表达式中通过‘\i’来引用前面第i个捕获内容,代码如下:

public static void main(String[] args) {
//目标字符串 假设我们要匹配一段被双引号或者单引号修饰的字符串
String s = "\"src\"";
//创建匹配模式
Pattern pattern = Pattern.compile("^([\"'])[^\"]+\\1$");
//得到匹配器
Matcher matcher = pattern.matcher(s);
//打印匹配结果
System.out.println("isMatch="+matcher.matches());
}

输出为:
isMatch=true

[color=red]注意:[/color]‘\1’引用的是第一个捕获的实际内容,而不是表达式里括号的内容。也就是说,如果目标字符串右侧的双引号变成单引号,那么结果为false。

我们也可以在替换字符串的时候来引用捕获的内容,代码如下:

public static void main(String[] args) {
//目标字符串 把所有的小数后面2位以后的部分截掉,不考虑四舍五入
String s = "a:3.567 b:1.2355 c:0.4401";
//创建匹配模式
Pattern pattern = Pattern.compile("(\\d\\.\\d\\d)\\d*");
//得到匹配器
Matcher matcher = pattern.matcher(s);

s = matcher.replaceAll("$1");

System.out.println("s="+s);
}

输出为:
s=a:3.56 b:1.23 c:0.44

上面的代码也可以直接写成:

s = s.replaceAll("(\\d\\.\\d\\d)\\d*", "$1");


关于Java正则表达式一些基础的东西简单总结到这里。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值