啥都不说,先直接上代码!
public static void main(String[] args) {
String s = "2012年2月4日,发自95535:您的尾号2354的银行卡于12:21在ATM机支出23元【中国银行】" +
"2012年2月24日,发自95535:您的尾号2354的银行卡于12:21在ATM机支出23元【中国】";
Pattern pattern = Pattern.compile("(?<date>\\d+年\\d+月\\d+日)(.*?)(?<phone>\\d+)(.*?)(?<card>\\d+)(.*?)(?<inout>(收入)|(支出))(?<num>\\d+)元【(?<bank>.*?)】");
Matcher matcher = pattern.matcher(s);
while (matcher.find()){
String date = matcher.group("date");
String bank=matcher.group("bank");
System.out.println(date);
System.out.println(bank);
}
}
接着我们看看打印的结果:
D:\JDK\bin\java...
2012年2月4日
中国银行
2012年2月24日
中国
我们可以看到,这里把两行的时间和银行名称都已经打印出来了,然后我给大家解释下这行正则表达式的含义。
1.第一个括号(?<>\\d+年\\d+月\\d+日);
- ?<> :这个是给括号内匹配到的内容命名,方便后面从Matcher里面获取该内容。
- \\d+:其实是\d,第一个\是转意,\d表示匹配一个数字,+表示匹配1个或一个以上的内容,所以\\d+匹配到了2012。
- 年:上面的\\d+匹配到年就停止了。
- 第二个\\d+:和上面一样到月这里停止了,所以匹配到了2。
后面的日一样。
总结:正则表达式只能匹配一个内容如,String s=“2018"用\d只能匹配到“2”,要想匹配到“2018“需要用\d+或\d*。(?\\d+年\\d+月\\d+日)匹配到了"2012年2月4日”,并命名为"data"。
2.第二个括号(.*?)
- .:表示任意不是换行的字符。
- *:表示匹配0个或0个以上的内容,和上面的+有细微的区别。
- ?:表示非贪婪模式,正则表达式默认为贪婪模式,默认匹配到最后一个目标,而?的作用是匹配到第一个目标就停止了。
总结:(.*?)匹配到的内容为“,发自”,到接下来有数字的地方就停止了,为什么?因为后面的括号内容为(?\\d+),看到了吗\\d+它是匹配数字的。还有就是为什么我们不需要“,发自”这个内容为什么要求匹配它,因为没有他我们后面的(?\\d+)就匹配不到“95535”。所以还有个结论:匹配时一定是连续的,也就是前面的内容要被匹配了,我们接下来的内容才会被匹配到!
3.第三个括号(?\d+)
上面讲过了就不赘述。
总结:(?\d+)匹配到了“95535”,并将内容命名为"phone"。
4.第四个括号(.*?)
上面讲过了就不赘述。在此代码中起连接作用。
总结:正则表达式需要连续匹配,接下来的内容才能被匹配到!
5.第七个括号(?(收入)|(支出))
- (收入)|(支出):表示支出或收入都能被匹配到。
总结:‘“|”两边的内容都能被匹配到
最后,给大家一下常用的匹配符号,把下面的符号用熟,基本上在平时工作中就够了,不过要想成为大牛,那还得加油哦!
符号 | 含义 |
---|---|
. | 任意非换行符 |
\d | 数字 |
\D | 非数字 |
* | >=0 |
+ | >0 |
? | 非贪婪模式 |
?<> | 命名分组 |
^ | 匹配开头 |
$ | 匹配结尾 |
?i() | 忽略小括号内容的大小写 |
[a-zA-Z0-9] | 匹配单个是否为a-zA-Z0-9的内容 |
[a-zA-Z] | 匹配单个是否为字母 |
[0-9] | 匹配单个是否为数字(这三个([a-zA-Z0-9])可以在大括号随意组合) |