内容学习于:edu.aliyun.com
1. 认识正则表达式
通过之前一系列的分析可以发现,String 是一个非常万能的类型,因为String不仅仅可以支持有各种字符串的处理操作,也支持有向各个数据类型的转换功能,所以在项目的开发之中,只要是用户输入的信息基本上都用String表示。于是在向其它数据类型转换的时候,为了保证转换的正确性,往往需要对其进行一些复杂的验证处理,那么这种情况下如果只是单纯的依靠String类中的方法是非常麻烦的。
现在假设有一个字符串要求你判断字符串是否由数字所组成,如果由数字所组成则将其变为数字进行乘法计算。
判断字符串是否全是数字代码:
public class JavaAPIDemo {
public static void main(String[] args) {
String str = "123";
if (isNum(str)) {
int num = Integer.parseInt(str);
System.out.println(num * 2);
}
}
public static boolean isNum(String str) {
char data[] = str.toCharArray();
for (char temp : data) {
if (temp > '9' || temp < '0') {
return false;
}
}
return true;
}
}
结果:
246
实际上这种验证的功能是非常简单的,但是这如此简单的功能却需要开发者编写大量的程序逻辑代码,那么如果是更加复杂的验证呢?那么在这样的情况下,对于验证来讲最好的做法就是利用正则表达式来完成。
正则表达式代码:
public class JavaAPIDemo {
public static void main(String[] args) {
String str = "123";
if (str.matches("\\d+")) {//正则表达式
int num = Integer.parseInt(str);
System.out.println(num * 2);
}
}
}
结果:
246
正则表达式最早是从Perl语言里面发展而来的,而后在JDK1.4以前如果需要使用到正则表达式的相关定义则需要单独引入其它的*.jar文件,但是从JDK 1.4之后,正则已经默认被JDK所支持,并且提供有java.util.regex开发包,同时针对于String类进行了一些修改,使其可以有方法直接支持正则处理。
<mark>使用正则最大的特点在于方便进行验证处理,以及方便进行复杂字符串的修改处理。</mark>
2. 常用正则表达式(背)
<mark>注:使用时若在字符串中表示,需要利用“\”转义“\”,即使用两个“\”</mark>
如果要想进行正则的处理操作,那么就首先需要对常用的正则标记有所掌握,从JDK 1.4开始提供有java.util.regex 开发包,这个包里面提供有一个Pattern程序类,在这个程序类里面定义有所有支持的正则标记。
a. 【数量:单个】字符匹配:
x:表示由任意字符组成
\:表示“\”
\n:匹配换行
\t:匹配制表符
b. 【数量:单个】字符集(可以从里面任选一个字符):
[abc]:表示可能是a、b和c的任意一个
[^abc]:表示不是a、b和c的任意一个
[a-zA-Z]:表示由一个字母所组成,不区分大小写
[0-9]:表示由一个数字组成
c. 【数量:单个】简化字符集:
.:表示任意一个字符
\d:等价于[0-9]
\D:等价于[^0-9]
\s:匹配任意的一位空格,可能是空格、换行、制表符
\S:匹配任意的非空格数据
\w:匹配字母,数字,下划线,等价于[a-zA-Z_0-9]
\W:匹配非字母,数字,下划线,等价于[a-zA-Z_0-9]
d. 边界匹配:
^:表示边界匹配开始
$:表示边界匹配结束
e. 数量匹配:
表达式?:该正则可以出现0次或1次
表达式*:该正则可以出现0次、1次或多次
表达式+:该正则可以出现1次或多次
表达式{n}:表示表达式的长度正好为n次
表达式{n,}:表示表达式的长度正好为n次以上
表达式{n,m}:表示表达式的长度正好为n次到m次之间
f. 逻辑表达式:可以连接多个正则
表达式X表达式Y:表示表达式X紧跟着表达式Y
表达式X|表达式Y:表达式X或表达式Y
(表达式):为表达式设置一个整体描述,可以为整体描述设置数量单位
代码:
例子1:
public class JavaAPIDemo {
public static void main(String[] args) {
String str = "aa";//要匹配的数据
String regex = "a";//正则规则
System.out.println(str.matches(regex));//没法匹配数量
}
}
结果:
false
例子2:
public class JavaAPIDemo {
public static void main(String[] args) {
String str = "a";//要匹配的数据
String regex = "[abc]";//正则规则
System.out.println(str.matches(regex));
}
}
结果:
true
例子3:
public class JavaAPIDemo {
public static void main(String[] args) {
String str = "2";//要匹配的数据
String regex = "[a-zA-Z]";//正则规则
System.out.println(str.matches(regex));
}
}
结果:
false
例子4:
public class JavaAPIDemo {
public static void main(String[] args) {
String str = "a";//要匹配的数据
String regex = "[0-9]";//正则规则
System.out.println(str.matches(regex));
}
}
结果:
false
例子5:
public class JavaAPIDemo {
public static void main(String[] args) {
String str = "a\n";//要匹配的数据
String regex = "\\D\\s";//正则规则
System.out.println(str.matches(regex));
}
}
结果:
true
例子6:
public class JavaAPIDemo {
public static void main(String[] args) {
String str = "aadad";//要匹配的数据
String regex = "\\w+";//正则规则
System.out.println(str.matches(regex));
}
}
结果:
true
例子7:
public class JavaAPIDemo {
public static void main(String[] args) {
String str = "aadad";//要匹配的数据
String regex = "\\w{3,5}";//正则规则
System.out.println(str.matches(regex));
}
}
结果:
true
3. String类对正则的支持
在进行正则表达式大部分处理的情况下都会基于String类来完成,并且在String类里面提供有如下与正则有关的操作方法:
NO | 方法名称 | 类型 | 描述 |
---|---|---|---|
01 | public boolean matches(String regex) | 普通 | 将指定字符串进行正则判断 |
02 | public String replaceAll(String regex,String replacement) | 普通 | 替换全部 |
03 | public String replaceFirst(String regex,String replacement) | 普通 | 替换首个 |
04 | public String[] split(String regex) | 普通 | 正则拆分 |
05 | public String[] split(String regex,int limit) | 普通 | 正则拆分 |
实现字符串的替换(删除非字母和数字)代码:
public class JavaAPIDemo {
public static void main(String[] args) {
String str = "hlo8rk[p';{/;kfa[/'//k;j;a;f4+*+*/+4+-;";//要匹配的数据
String regex = "[^a-zA-Z0-9]+";//正则规则
System.out.println(str.replaceAll(regex,""));
}
}
结果:
hlo8rkpkfakjaf44
实现字符串的拆分代码:
public class JavaAPIDemo {
public static void main(String[] args) {
String str = "gi981o89h9o0093171hdiau9o1hdo91gido9119814";//要匹配的数据
String regex = "\\d+";//正则规则
String result[] = str.split(regex);
for (String temp : result) {
System.out.printf(temp + "、");
}
}
}
结果:
gi、o、h、o、hdiau、o、hdo、gido、
在正则处理的时候对于拆分与替换的操作相对容易–些,但是比较麻烦的是数据验证部分。
判断是否为小数代码:
public class JavaAPIDemo {
public static void main(String[] args) {
String str = "100.";//要匹配的数据
String regex = "\\d+(\\.\\d)?\\d*";//正则规则
System.out.println(str.matches(regex));
}
}
结果:
false
判断是否为日期代码:
public class JavaAPIDemo {
public static void main(String[] args) throws ParseException {
String str = "2000-09-09";//要匹配的数据
String regex = "\\d{4}-\\d{2}-\\d{2}";//正则规则
if (str.matches(regex)) {
System.out.println(new SimpleDateFormat("yyyy-MM-dd").parse(str));
}
}
}
结果:
Sat Sep 09 00:00:00 CST 2000
<mark>需要注意的是,正则表达式无法对里面的内容进行判断,只能够对格式进行判断处理。</mark>
判断电话号码代码:
public class JavaAPIDemo {
public static void main(String[] args) throws ParseException {
String str1 = "51283346";//要匹配的数据
String str2 = "01051283346";//要匹配的数据
String str3 = "(010)-51283346";//要匹配的数据
String regex = "((\\d{3,4})|(\\(\\d{3,4}\\)-))?\\d{7,8}";//正则规则
System.out.println("【电话格式1】:" + str1.matches(regex));
System.out.println("【电话格式2】:" + str2.matches(regex));
System.out.println("【电话格式3】:" + str3.matches(regex));
}
}
结果:
【电话格式1】:true
【电话格式2】:true
【电话格式3】:true
既然已经可以使用正则进行验证了,那么下面就可以利用其来实现一个email地址格式的验证。
- 范例:验证email格式
- email的用户名可以由字母、数字、_ 所组成(不应该使用“”开头);
- email 的域名可以由字母、数字、_、-所组成;
- 域名的后缀必须是: .cn、 .com、 .net、 .com.cn、 .gov;
验证email格式代码:
public class JavaAPIDemo {
public static void main(String[] args) throws ParseException {
String str1 = "mldnjava888@mldn.com.cn";//要匹配的数据
String regex = "[a-zA-Z0-9]\\w+@\\w+\\.((cn)|(com)|(com\\.cn)|(gov))";//正则规则
System.out.println("【邮箱】:" + str1.matches(regex));
}
}
结果:
【邮箱】:true
4. java.util.regex包支持
虽然在大部分的情况下都可以利用String类实现正则的操作,但是也有一些情况下需要使用到java.util.regex开发包中提供的正则处理类,在这个包里面一共定义有两个类: Pattern (正则表达式编译)、Matcher (匹配)。
Pattern有两个方法:
- 编译:public static Pattern compile(String regex)
- 字符串拆分:public String[] split(CharSequence input)
字符串拆分代码:
public class JavaAPIDemo {
public static void main(String[] args) throws ParseException {
String str1 = "ada*&**IVNG*OIB(OJB(*&((YO*)*&*^%&^&(*OO:U";//要匹配的数据
String regex = "[^a-zA-Z]+";//正则规则
Pattern pattern = Pattern.compile(regex);//编译
String[] result = pattern.split(str1);//拆分
for (String t : result) {
System.out.println(t);
}
}
}
结果:
ada
IVNG
OIB
OJB
YO
OO
U
Matcher 类,实现了正则匹配的处理类,这个类的对象实例化依靠Pattern 类完成:
Pattern 类提供的方法: public Matcher matcher(CharSequence input);
当获取了Matcher类的对象之后就可以利用该类中的方法进行如下操作:
- 匹配方法:public boolean matches()
- 字符串替换:public String replaceAll(String replacement)
字符串匹配代码:
public class JavaAPIDemo {
public static void main(String[] args) throws ParseException {
String str1 = "6513";//要匹配的数据
String regex = "\\d+";//正则规则
Pattern pattern = Pattern.compile(regex);//编译
Matcher matcher = pattern.matcher(str1);
System.out.println(matcher.matches());
}
}
结果:
true
如果纯粹的是以拆分、替换、匹配三种操作为例根本用不到java.util.regex开发包,只依靠String类就都可以实现了。<mark>但是Matcher类里面提供有一种分组的功能,而这种分组的功能是String不具备的。</mark>
代码:
public class JavaAPIDemo {
public static void main(String[] args) throws ParseException {
String str1 = "INSERT INTO dept(deptno,dname,loc) VALUES (#{deptnp},#{dname},#{loc})";//要匹配的数据
String regex = "#\\{\\w+\\}";//正则规则
Pattern pattern = Pattern.compile(regex);//编译
Matcher matcher = pattern.matcher(str1);
while (matcher.find()){//是否有匹配的内容
System.out.println(matcher.group(0).replaceAll("#|\\{|\\}",""));
}
}
}
结果:
deptnp
dname
loc
java.util.regex开发包,如果不是进行一些更为复杂的正则处理是很难使用到的,而String类所提供的功能只适合于正则的基本操作。