正则表达式(Regular Expression)是在 JDK1.4 中引入的功能。正则表达式可以方便地对数据进行匹配,可以执行更加复杂的字符串拆分、验证、替换等操作。例如,现在要求判断一个字符串是否由数字组成,则可以有以下两种做法。
实例 1 :判断一个字符串是否由数字组成
方案一:判断一个字符串是否由数字组成
package self.learn.regularexpression;
public class RegexDemo01 {
public static void main(String[] args) {
String str = "123456789"; // 此字符串由数字组成
boolean flag = true;
char c[] = str.toCharArray(); // 将字符串变为字符数组
for(int i = 0; i < c.length; i++) { // 依次判断
if(c[i] < '0'||c[i] > '9') { // 判断每一个字符是否是 0-9
flag = false; // 如果不是则退出循环
break;
}
}
if(flag) { // 判断输出
System.out.println("是由数字组成!");
}else {
System.out.println("不是由数字组成!");
}
}
}
方案二:判断一个字符串是否由数字组成(使用正则表达式验证)
package self.learn.regularexpression;
import java.util.regex.Pattern;
public class RegexDemo01 {
public static void main(String[] args) {
String str = "123456789"; // 此字符串由数字组成
if(Pattern.compile("[0-9]+").matcher(str).matches()) {
System.out.println("是由数字组成!");
}else {
System.out.println("不是由数字组成!");
}
}
}
上面的代码完成了和第一个范例同样的功能,但是代码的长度要比第一个程序短的多。实际上,上面的程序就是使用正则表达式进行验证的,而中间的 “[0-9]+” 就是正则表达式的匹配字符,表示的含义是:由 1 个以上的数字组成的。实际上,具体的正则表达式操作类是需要通过 Pattern 和 Matcher 两个类完成的。
1 Pattern 类和 Matcher 类
如果想要在程序中使用正则表达式 ,则必须依靠 Pattern 类和 Matcher 类,这两个类都在 java.util.regex。 Pattern 类主要是规范正则表达式的编写(如上面代码中的 [0-9] 的编写),而 Matcher 类主要是执行规范,验证一个字符串是否符合其规范。
1.1 常用的正则规范的定义如表:
序号 | 规范 | 描述 | 序号 | 规范 | 描述 |
---|---|---|---|---|---|
1 | \\ | 表示反斜线 | 9 | \w | 表示字母、数字、下划线 |
2 | \t | 表示制表符 | 10 | \W | 表示非字母、数字、下划线 |
3 | \n | 换行 | 11 | \s | 表示所有空白符(换行、空格等) |
4 | [abc] | 字符 a、b 或 c | 12 | \S | 表示所有非空白符 |
5 | [^abc] | 除了字符 a、b 、c 之外的任意字符 | 13 | ^ | 行的开头 |
6 | [a-zA-Z0-9] | 表示由字符数字组成 | 14 | $ | 行的结尾 |
7 | \d | 表示数字 | 15 | . | 匹配除换行符之外的任意字符 |
8 | \D | 表示非数字 |
数量表示(X 表示一组规范)
序号 | 规范 | 描述 | 序号 | 规范 | 描述 |
---|---|---|---|---|---|
1 | X | 必须出现一次 | 5 | X{n} | 必须出现 n 次 |
2 | X? | 可以出现 0 次或 1 次 | 6 | X{n, } | 必须出现 n 次以上 |
3 | X* | 可以出现 0 次、 1 次或多次 | 7 | X{n, m} | 必须出现 n~m 次 |
4 | X+ | 可以出现 1 次或多次 |
逻辑运算符(X、Y 表示一组规范)
序号 | 规范 | 描述 | 序号 | 规范 | 描述 |
---|---|---|---|---|---|
1 | XY 规范后跟着Y | X规范后跟着Y 规范 | 3 | (X) | 作为一个捕获数组规范 |
2 | X|Y | X规范或Y 规范 |
Pattern 类常用方法如表
序号 | 方法 | 类型 | 描述 |
---|---|---|---|
1 | public static Pattern compile(String regex) |
普通 | 指定正则表达规则 |
2 | public Matcher matcher(CharSequence input) |
普通 | 返回 Mattcher 类实例 |
3 | public String[] split(CharSequence input) |
普通 | 字符串拆分 |
在 Pattern 类中,如果要想取得 Pattern 类实例,则必须调用 compile()方法
如果要验证一个字符串是否符合规范,则可以使用 Matcher 类。
Matcher 类常用方法如表
序号 | 方法 | 类型 | 描述 |
---|---|---|---|
1 | public boolean matches() |
普通 | 执行验证 |
2 | public String replaceAll(String replacement) |
普通 | 字符串替换 |
实例 2 :验证一个字符串是否是合法的日期格式
(1)日期格式要求:yyyy-mm-dd
(2)正则表达式如下:
日期:1983 - 07 - 27
格式:四位数字 两位数字 两位数字
正则:\d{4} - \d{2} - \d{2}
代码:
package self.learn.regularexpression;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexDemo01 {
public static void main(String[] args) {
String str = "1983-07-27"; // 此字符串由数字组成
String pat = "\\d{4}-\\d{2}-\\d{2}"; // 定义验证规则
Pattern p = Pattern.compile(pat); // 实例化 Pattern 类
Matcher m = p.matcher(str); // 验证字符串内容是否合法
if(m.matches()) {
System.out.println("日期格式合法!");
}else {
System.out.println("日期格式不合法!");
}
}
}
运行结果截图:
在上面的程序中,“\” 字符是需要进行转义的,两个 “\” 实际上表示的是一个 “\” ,所以“\d” 表示的是 “\d”。
实例 3:按照字符串的数字将字符串拆分(使用 Pattern 类对字符串进行拆分)
代码:
package self.learn.regularexpression;
import java.util.regex.Pattern;
public class RegexDemo01 {
public static void main(String[] args) {
String str = "A11B3332C456E7789234F"; // 此字符串由数字组成
String pat = "\\d+"; // 定义验证规则
Pattern p = Pattern.compile(pat); // 实例化 Pattern 类
String s[] = p.split(str); // 进行字符串拆分
for(int i = 0; i < s.length; i++) {
System.out.print(s[i]+" ");
}
}
}
运行结果截图:
实例 4:将全部数字替换成 “_” (Matcher 类中的替换操作)
代码:
package self.learn.regularexpression;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexDemo01 {
public static void main(String[] args) {
String str = "A11B3332C456E7789234F"; // 此字符串由数字组成
String pat = "\\d+"; // 定义验证规则
Pattern p = Pattern.compile(pat); // 实例化 Pattern 类
Matcher m = p.matcher(str); // 实例化 Matcher 类
String string = m.replaceAll("_"); // 替换数字
System.out.println(string);
}
}
运行结果截图:
2 String 类对正则表达式的支持
序号 | 方法 | 类型 | 描述 |
---|---|---|---|
1 | public boolean matches(String regex) |
普通 | 字符串匹配 |
2 | public String replaceAll(String regex,String replacement) |
普通 | 字符串替换 |
3 | public String[] split(String regex) |
普通 | 字符串拆分 |
实例 5:使用 String 类修改之前的操作
package self.learn.regularexpression;
public class RegexDemo01 {
public static void main(String[] args) {
String str = "A11B3332C456E7789234F".replaceAll("\\d+", "_"); // 字符串替换
boolean temp = "1983-07-27".matches("\\d{4}-\\d{2}-\\d{2}"); // 字符串匹配
String s[] = "A11B3332C456E7789234F".split("\\d+"); // 字符串拆分
System.out.println("字符串替换操作: "+str);
System.out.println("字符串验证操作: "+temp);
System.out.print("字符串拆分:");
for(int i = 0; i < s.length; i++) {
System.out.print(s[i]+" ");
}
}
}
运行结果截图:
可以发现,上面的程序运行结果和之前的是一样的,所以建议读者以后最好直接使用 String 类中的方法,这样会比较方便。