字符串是一个非常万能的类型,它不仅仅可以进行修改,还可以向各个数据类型进行转换,用户输入的信息基本上都用字符串接收。于是在向其他数据类型转换的时候,为了保证转换的正确性,往往要进行验证处理,如果仅靠字符串本身的方法是非常麻烦的,在这种情况下,就出现了正则表达式。
正则表达式从 Perl 语言发展而来。在 JDK 1.4 之后,正则表达式被默认支持。提供java.util.regex开发包,针对String类也提出了一些修改,所以有方法直接支持正则处理。
常用正则标记
在java.util.regex有一个Pattern类,在这个类中定义了所有正则标记类。
字符匹配
| 正则表达式 | 匹配内容 |
|---|---|
| 任意字符 | 这个字符 |
| \\ | \ |
| \n | 换行 |
| \t | 制表符 |
| [abc] | abc 任意一个 |
| [^abc] | 不是 abc 任意一个 |
| [a-zA-Z] | 一个任意字母,不区分大小写 |
| [0-9] | 一位数字 |
| . | 任意一个字符 |
| \d | 一个数字,等价于 [0-9] |
| \D | 不是一个数字 |
| \s | 任意一位空格,可能是空格、换行、制表符 |
| \S | 任意一位非空格 |
| \w | 字母、数字、下划线 |
| \W | 非字母、数字、下划线 |
| ^ | 边界开始 |
| $ | 边界结束 |
多位字符匹配
| 正则表达式 | 匹配内容 |
|---|---|
| 表达式? | 该表达式出现 0 或 1 次 |
| 表达式 * | 该表达式出现 0 或多次 |
| 表达式 + | 该表达式出现 1 或多次 |
| 表达式 {n} | 表达式出现 n 次 |
| 表达式 {n,} | 表达式出现 n 次及以上 |
| 表达式 {n,m} | 表达式出现 [n, m] 次 |
逻辑表达式
| 正则表达式 | 匹配内容 |
|---|---|
| 表达式 X 表达式 Y | X 表达式跟上 Y 表达式 |
| 表达式 X|表达式 Y | 有一个满足即可 |
| (表达式) | 整体绑定 |
String 对正则的支持
- 将字符串进行正则判断
public boolean matches(String regex) - 将字符串符合正则的进行替换
public String replaceAll(String regex, String replacement) - 替换首个
public String replaceFirst(String regex, String replacement) - 正则拆分
public String[] split(String regex) - 拆分成 limit 个
public String[] split(String regex, int limit)
案例
删除非字母与数字
public class Test {
public static void main(String[] args) {
String str = "nfsdj#$%#$SDafg23r@#sadg2334";
String regex = "[^a-zA-Z0-9]*";
System.out.println(str.replaceAll(regex, ""));
}
}
按数字拆分
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
String str = "sdfsfa213sdfas2dsfa23";
String regex = "\\d*";
System.out.println(Arrays.toString(str.split(regex)));
}
}
判断一个数据是否为小数
public class Test {
public static void main(String[] args) {
String str = "100.1";
String regex = "\\d+\\.\\d+";
System.out.println(str.matches(regex));
}
}
判断是否由日期组成,若是则转换为 Date
import java.text.ParseException;
import java.text.SimpleDateFormat;
public class Test {
public static void main(String[] args) throws ParseException {
String str = "1939-12-22";
String regex = "\\d{4}-\\d{2}-\\d{2}";
if (str.matches(regex)) {
System.out.println(new SimpleDateFormat("yyyy-MM-dd").parse(str));
}
}
}
验证电子邮件格式
import java.text.ParseException;
public class Test {
public static void main(String[] args) throws ParseException {
String str = "sdf@df.com";
String regex = "[a-zA-Z0-9]\\w+@[\\w-]+\\.(cn|com|net|org)";
System.out.println(str.matches(regex));
}
}
java.util.regex 开发包
这个包内定义有两个类:
Pattern
import java.text.ParseException;
import java.util.Arrays;
import java.util.regex.Pattern;
public class Test {
public static void main(String[] args) throws ParseException {
String str = "sfsadf123dsf@!#SDF12rFSD!@";
String regex = "[^a-zA-Z]+";
Pattern pat = Pattern.compile(regex);
String[] result = pat.split(str);
System.out.println(Arrays.toString(result));
}
}
Matcher
实现了正则匹配处理类,这个类的对象实例化依靠Pattern类完成。
import java.text.ParseException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test {
public static void main(String[] args) throws ParseException {
String str = "101";
String regex = "\\d+";
Pattern pat = Pattern.compile(regex);
Matcher mat = pat.matcher(str);
System.out.println(mat.matches());
}
}
如果纯粹的拆分、替换、匹配没有必要使用这个包,但是有一种分组的功能是其他方法不具备的:分组。
import java.text.ParseException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test {
public static void main(String[] args) throws ParseException {
String str = "sdfasdfadsfdas (#{asdf}, #{sdaf},#{sdf})";
String regex = "#\\{\\w+\\}"; // 匹配 #{} 里的内容
Pattern pat = Pattern.compile(regex);
Matcher mat = pat.matcher(str);
while (mat.find()) {
System.out.println(mat.group());
}
}
}