概述
正则表达式,又称正规表示法、常规表示法(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。
又或者可以这样理解:正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。
所以,如果给定一个正则表达式和另一个字符串,我们可以达到如下的目的:
- 给定的字符串是否符合正则表达式的过滤逻辑(称作“匹配”);
- 可以通过正则表达式,从字符串中获取我们想要的特定部分。
特点
- 灵活性、逻辑性和功能性非常的强;
- 可以迅速地用极简单的方式达到字符串的复杂控制;
- 对于刚接触的人来说,比较晦涩难懂。
正则表达式的基础知识
学习正则其实就是在学习符号的使用,规则字符在java.util.regex.Pattern类中,下面将会列出常见的符号。
常见符号
字符
符号 | 说明 |
---|---|
x | 字符x |
\ | 反斜线 |
\t | 制表符 (‘\u0009’) |
\n | 换行 |
\r | 回车 |
\f | 换页符 (‘\u000C’) |
\a | 报警 (bell) 符 (‘\u0007’) |
字符类
符号 | 说明 |
---|---|
[abc] | a、b或c |
[^abc] | 任何字符,除了a、b或c |
[a-zA-Z] | a到z或A到Z,两头的字母包括在内(范围) |
[0-9] | 0到9的字符 |
预定义字符类
符号 | 说明 |
---|---|
. | 任何字符 |
\d | 数字:[0-9] |
\D | 非数字:[^0-9] |
\s | 空白字符:[ \t\n\x0B\f\r] |
\S | 非空白字符:[^\s] |
\w | 单词字符:[a-zA-Z_0-9] |
\W | 非单词字符:[^\w] |
边界匹配器
符号 | 说明 |
---|---|
^ | 行开头 |
$ | 行结尾 |
\b | 单词边界 |
\B | 非单词边界 |
Greedy数量词
符号 | 说明 |
---|---|
X? | X,一次或一次也没有 |
X* | X,零次或多次 |
X+ | X,一次或多次 |
X{n} | X,恰好n次 |
X{n,} | X,至少n次 |
X{n,m} | X,至少n次,但是不超过m次 |
正则表达式的常用功能
正则表达式的常用功能有匹配、切割、替换以及获取,下面会一一讲解。
匹配
String类中提供了匹配的方法:
public boolean matches(String regex):编译给定正则表达式并尝试将给定输入与其匹配。
例一,校验QQ,要求QQ号5~15位、只能是数字、0不能开头。
package cn.liayun.regex;
public class RegexSimple {
public static void main(String[] args) {
matchesDemo();
}
public static void matchesDemo() {
//QQ,要求QQ号5~15位、只能是数字、0不能开头。
String QQ = "12345";
String regex = "[1-9]\\d{4,14}";
boolean b = QQ.matches(regex);
System.out.println(QQ + ":" + b);
}
}
例二,校验手机号码是否正确,例如15800001111。
package cn.liayun.regex;
public class RegexSimple {
public static void main(String[] args) {
matchesDemo();
}
public static void matchesDemo() {
// 需求:校验手机号码是否正确
String tel = "15800001111";
String regex = "1[358]\\d{9}";
boolean b = tel.matches(regex);
System.out.println(tel + ":" + b);
}
}
切割
String类中提供了切割的方法:
public String[] split(String regex):根据指定的正则表达式分割字符串。
案例如下,
package cn.liayun.regex;
public class RegexSimple {
public static void main(String[] args) {
splitDemo();
}
public static void splitDemo() {
// String temp = "zhangsan lisi wangwu";
// String regex = " +";//按照空格来切割字符串
// String temp = "zhangsan.lisi.wangwu";
// String regex = "\\.";//按照.来切割字符串
String temp = "qwe##rty$$$$$iouzzzzzzztyu";
String regex = "(.)\\1+";//按照叠词来切割字符串。
//为了实现规则的复用,用()将需要复用的规则封装,
//就称为正则表达式中的组,每一个都有编号,从1开始。
//通过使用编号就可以复用对应组的规则内容。注意,编号必须用在组的后面。
//也就是说,先封装完再调用。
String[] names = temp.split(regex);
for (String name : names) {
System.out.println("-" + name + "-");
}
}
}
以上实例程序中,提到了组的概念。为了实现规则的复用,用()将需要复用的规则封装,就称为正则表达式中的组,每一个组都有编号,从1开始,通过使用编号就可以复用对应组的规则内容。注意,编号必须用在组的后面。
替换
String类中提供了替换的方法:
public String replaceAll(String regex, String replacement):使用给定的replacement替换此字符串所有匹配给定的正则表达式的子字符串。
例一,手机号中间4位不能出现数字字符,用*替换。
package cn.liayun.regex;
public class RegexSimple {
public static void main(String[] args) {
replaceDemo();
}
public static void replaceDemo() {
String temp = "15900001111";
temp = temp.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");//$可以在多参数时,后面的参数可以通过$编号的形式取到前一个参数的组
System.out.println(temp);
}
}
这里又学到一点:$
符号可以在多参数调用时,后面的参数可以通过$编号
的形式取到前一个参数的组。
例二,将字符串中的多个叠词替换为一个。
package cn.liayun.regex;
public class RegexSimple {
public static void main(String[] args) {
replaceDemo();
}
public static void replaceDemo() {
String temp = "qwe##rty$$$$$iouzzzzzzztyu";
temp = temp.replaceAll("(.)\\1+", "$1");
System.out.println(temp);
}
}
获取
要想实现获取,将符合规则的内容取出来,就要用到正则表达式对象java.util.regex.Pattern和java.util.regex.Matcher了。典型的调用顺序是:
- 将字符串规则封装成Pattern对象,用的是compile(regex)方法;
- 通过正则对象获取匹配器对象,用于将正则规则作用到要操作的字符串上;
- 通过匹配器对象的方法对字符串进行操作。
用代码表示即可为:
Pattern p = Pattern.compile("a*b");//将规则编译成对象。
Matcher m = p.matcher("aaaaab");//和要操作的字符串关联,生成匹配器对象。
boolean b = m.matches();//使用匹配器对象的方法对字符串操作。
Matcher匹配器中的常用方法有:
符号 | 说明 |
---|---|
matches() | 匹配字符串 |
find() | 查找有没有满足条件的子串 |
group() | 获取满足条件的子串 |
例如,取出字符串“da jia zhu yi le,ming tian fang jia le!”中由三个字母组成的单词。
package cn.liayun.regex;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexSimple {
public static void main(String[] args) {
getDemo();
}
public static void getDemo() {
/*
* 要想实现获取:将符合规则的内容取出来。
* 用到正则表达式对象。java.util.regex.Pattern
*
* 1,将字符串规则封装成Pattern对象,用的是compile(regex)方法。
* 2,通过正则对象获取匹配器对象。用于将正则规则作用到要操作的字符串上。
* 3,通过匹配器对象的方法对字符串进行操作。
* Pattern p = Pattern.compile("a*b");//将规则编译成对象。
* Matcher m = p.matcher("aaaaab");//和要操作的字符串关联,生成匹配器对象。
* boolean b = m.matches();//使用匹配器对象的方法对字符串操作。
*/
//获取字符串中符合规则的内容。
String temp = "da jia zhu yi le,ming tian fang jia le!";
System.out.println(temp);
//取出由三个字母组成的单词。
String regex = "\\b[a-zA-Z]{3}\\b";
//1,将规则编译成Pattern对象
Pattern p = Pattern.compile(regex);
//2,和字符串关联,获取匹配器对象
Matcher m = p.matcher(temp);
// System.out.println(m.find());
// System.out.println(m.group());
while (m.find()) {
System.out.println(m.start() + ":" + m.group() + ":" + m.end());
}
}
}