字符串操作的高效工具—正则表达式
- 一 . 概述
- 1.1 认识正则表达式
- 1.2 正则表达式体验案例
- 二 . 使用
- 2.1 字符类
- 2.2 逻辑运算符
- 2.3 预定义字符
- 2.4 数量词
- 2.5 分组括号
- 2.6 字符串中常用含有正则表达式的方法
正则表达式(Regular Expression,简称 regex 或 regexp)是一种强大的文本模式匹配工具,用于字符串搜索、替换、验证和解析等操作。它由一系列字符组成,这些字符除了表示自己的字面意思外,还具有特殊的意义,可以用来描述、匹配一系列符合某个句法规则的字符串。
正则表达式在编程语言中广泛应用,如 Python、JavaScript、Java、C# 等,这几门语言都提供了内置的库或函数来支持正则表达式的操作。
那接下来 , 让我们一起研究一下正则表达式的便利之处吧 .
一 . 概述
1.1 认识正则表达式
由一些特定的字符组成的字符串校验规则就叫做正则表达式 , 正则表达式通常用来校验、检查字符串是否符合规则的 .
正则表达式只能针对字符串进行格式校验 , 常用于对用户输入的字符串数据进行校验 , 比如 : 在一些数据录入的场景中 , 要求年龄必须是 2 位的数字、用户名必须是 8 位长度而且只能包含大小写字母、手机号码的合法性、QQ 号码的合法性等等 .
1.2 正则表达式体验案例
案例 : 设计一个程序 , 让用户输入一个 QQ 号码 , 验证 QQ 号码的合法性 :
- QQ 号码必须是 5~15 位长度
- QQ 号码必须都是数字
- 首位不能为 0
如果使用正常思路编写的话 , 代码如下 :
public class Main {
private static boolean checkQQ(String qq) {
// 1. QQ 号码必须是 5~15 位长度
if (qq.length() < 5 || qq.length() > 15) {
return false;
}
// 2. QQ 号码首位不能为 0
if (qq.charAt(0) == '0') {
return false;
}
// 3. QQ 号码必须全部是数字
for (int i = 0; i < qq.length(); i++) {
char ch = qq.charAt(i);
if (ch < '0' || ch > '9') {
return false;
}
}
// 满足所有条件
return true;
}
}
如果我们使用正则表达式的话 , 只需要一行就能校验 QQ 号
public class Main {
private static boolean checkQQ(String qq) {
return qq.matches("[1-9][0-9]{4,14}");
}
}
二 . 使用
正则表达式在开发工作中通常是 CV 操作 , 许多开发者针对常见的校验操作已经写好正则表达式了 , 我们只需要无脑使用即可 .
2.1 字符类
方括号 [] 被用于指定字符
举例 :
- [abc] : 代表 a、b、c 字符中的一个
- [^abc] : 代表除 a、b、c 以外的任何字符
- [a-z] : 代表 a-z 的所有小写字符中的一个
- [A-Z] : 代表 A-Z 的所有大写字符中的一个
- [0-9] : 代表 0-9 之间的某个数字字符
- [a-zA-Z0-9] : 代表 a-z 或者 A-Z 或者 0-9 之间的任意一个字符
- [a-dm-p] : a~d 或者 m~p 之间的任意一个字符
通过 matches(正则表达式) 方法使用 , 如果匹配了正则表达式就返回 true, 否则就返回 false
public class Main {
// boolean matches(正则表达式): 如果匹配了正则表达式就返回 true, 否则就返回 false
public static void main(String[] args) {
// 1. 验证 str 是否以 h 开头, 以 d 结尾, 中间是 a、e、i、o、u 中的某个字符
System.out.println("had".matches("h[aeiou]d"));
// 2. 验证 str 是否以 h 开头, 以 d 结尾, 中间不是 a、e、i、o、u 中的某个字符
System.out.println("hwd".matches("h[^aeiou]d"));
// 3. 验证 str 是否以 a-z 的任何一个小写字母开头, 后面跟 ad
System.out.println("aad".matches("[a-z]ad"));
// 4. 验证 str 是否以 a-d 或者 m-p 之间的某个字符开头, 后面跟 ad
System.out.println("bad".matches("[a-dm-p]ad"));
}
}
2.2 逻辑运算符
&& : 并且
| : 或者
public class Main {
public static void main(String[] args) {
// 1. 要求字符串是除 a、e、i、o、u 以外的其他小写字符开头, 后面跟 ad
System.out.println("vad".matches("[a-z&&[^aeiou]]ad"));
// 2. 要求字符串是 a、e、i、o、u 中的某个小写字符开头, 后面跟 ad
System.out.println("aad".matches("[a|e|i|o|u]ad"));
System.out.println("aad".matches("[aeiou]ad"));// 简写
}
}
2.3 预定义字符
预定义字符用来简化字符类的书写
预定义字符 | 作用 |
---|---|
“.” | 匹配任何字符 |
“\d” | 任何数字 , [0-9] 的简写 |
“\D” | 任何非数字 , [^0-9] 的简写 |
“\s” | 空白字符 , [\t\n\x0B\f\r] 的简写 |
“\S” | 非空白字符 , [^\s] 的简写 |
“\w” | 单词字符 , [a-zA-Z_0-9] 的简写 |
“\W” | 非单词字符 , [^\w] 的简写 |
❓ 其中 , \w 表示 a-z、A-Z、_、0-9 之间的字符 , 那如果我们不想要 _ 该怎样编写这个正则表达式呢 ?
✔ [\w&&^_]
public class Main {
public static void main(String[] args) {
// 1. 验证 str 是否是三位数字
// \d\d\d 会报错, 需要进行转义
System.out.println("123".matches("\\d\\d\\d"));
// 2. 验证手机号: 1 开头、第二位: 3/5/8、剩下 9 位都是 0-9 的数字
System.out.println("13555555555".matches("1[358]\\d\\d\\d\\d\\d\\d\\d\\d\\d"));
// 3. 验证字符串是否以 h 开头, 以 d 结尾, 中间可以是任何字符
System.out.println("hed".matches("h.d"));
}
}
2.4 数量词
数量词 | 作用 |
---|---|
? | 0 次或 1 次 |
* | 0 次到多次 |
+ | 1 次或多次 |
{n} | 恰好 n 次 |
{n,} | 至少 n 次 |
{n,m} | [n,m] 次 |
public class Main {
public static void main(String[] args) {
// 1. 验证 str 是否是 3 位数字
// \d: 任何数字, [0-9] 的简写
// {n}: 恰好 n 次
System.out.println("123".matches("\\d{3}"));
// 2. 验证 str 是否是多位数字
// \d: 任何数字, [0-9] 的简写
// +: 一次或多次
System.out.println("123456".matches("\\d+"));
// 3. 验证 str 是否是手机号(1 开头、第二位为 3/5/8、剩下 9 位都为 0-9 之间的数字)
// []: 匹配 [] 中的任意一个字符
// \d: 任何数字, [0-9] 的简写
// {n}: 恰好 n 次
System.out.println("13555555555".matches("1[358]\\d{9}"));
// 4. 验证 QQ 号码(① 5~15 位 ② 全部都是数字 ③ 第一位不是 0)
// []: 匹配 [] 中的任意一个字符
// \d: 任何数字, [0-9] 的简写
// {n,m}: 出现了 [n,m] 次
System.out.println("111111111".matches("[1-9]\\d{4,14}"));
}
}
2.5 分组括号
分组括号是指将需要重复使用的正则用小括号括起来 , 当做一个小组来看待
比如 : 我们 Windows 的激活码 , 就可以使用分组括号的形式验证
X9T5Q-L7V8D-J2F3M-N1K4R-P6Z7Y
我们分析一下激活码的特征
- 前四组 : 由数字 / 字母和一个减号组成 , 对应的正则为 [A-Z0-9]{5}-
- 最后一组 : 只由数字 / 字母组成 , 对应的正则为 [A-Z0-9]{5}
那最终的正则 , 我们就可以使用小括号将需要重复使用的正则括起来 , 这样就能重复使用了
([A-Z0-9]{5}-){4}[A-Z0-9]{5}
public class Main {
public static void main(String[] args) {
// 验证 Windows 激活码是否正确
// 特征: 前四组由 数字/字母 和 - 组成, 最后一组由 数字/字母 组成
System.out.println("X9T5Q-L7V8D-J2F3M-N1K4R-P6Z7Y".matches("([A-Z0-9]{5}-){4}[A-Z0-9]{5}"));
}
}
2.6 字符串中常用含有正则表达式的方法
String[] split (String regex) : 将当前字符串中匹配 regex 正则表达式的符号作为分隔符来切割字符串
String replaceAll (String regex , String newStr) : 将当前字符串中匹配 regex 正则表达式的字符串替换成 newStr
案例 1 : 将字符串按照数字进行切割
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
// 将字符串按照数字进行切割
String str = "a1b2c3d4e5f6g7h8i9j10";
// 通过正则表达式, 匹配 str 字符串中的数字, 按照数字切割字符串
// \d: 任何数字, [0-9] 的简写
// +: 出现一次或多次
String[] strs = str.split("\\d+");
System.out.println(Arrays.toString(strs));
}
}
案例 2 : 将字符串中的隐秘信息替换成 *
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
// 将字符串中的隐秘信息替换成 *
String str = "账号: 10086 密码: 10010";
// \d: 任何数字, [0-9] 的简写
// {n,}: 至少出现 n 次
String encipher = str.replaceAll("\\d{3,}", "*");
System.out.println("加密后的信息为 : " + encipher);
}
}
对于正则表达式的简单介绍就结束了 , 后续可以通过一些工具自动生成正则表达式 .
如果这篇文章对你有帮助的话 , 还请一键三连~ 您的支持是对我最大的鼓舞