正则表达式是针对字符串的提取,所有语言都支持,不管是前端的JS还是后端PHP,还包含了测试工具Jmeter,SQL,Linux上的find等等,对于开发来说,很重要,并且掌握后对一些字符工具操作会很方便
正则表达式主要是使用各类符号或者字母来表达,用到的符号看似很多,但有些符号是从另外的符号中扩展而来的,比如想要匹配一个数字时可以使用 [0-9]
,也可以用\d
来简化写法,\d
就是扩展用来匹配数字的。扩展的符号多了看上去匹配词就感觉很多,实则先学习它基本的匹配词后再去记扩展词就会容易很多。
学习正则的时候可以将使用到的符号就行分为几大类,先从基础的匹配到复杂的提取,层级递进从而达到螺旋式上升。比如[0-9]
代表匹配0到9数字;{2}代表至少满足两次前面的字符,连起来就是[0-9]{2}
就是一个正则表达式,能匹配到的长度为2的数字;^
代表开头,连起来就是^[0-9]{2}
,匹配以两位数字开头字符。
首先我将正则使用到的符号分为几大类:匹配符、限定符、定位符、装饰符和运算符号的优先级来就行练习,逐一掌握
在一串字符中,想要匹配数字、字母或者是符号,我们就可以根据这些特性然后使用特定的字符来做匹配提取
字符 | 说明 |
---|---|
. | 匹配所有单个字符,除了\r 、\n |
| | 或者,当表达式中出现非关键字的字符时就代表需匹配该字符。使用` |
[] | 包含其中的一个字符,例如[abc]匹配"are"里的a |
- | 字符范围。匹配指定范围内的任何字符。例如,[a-z] 匹配"a"到"z"范围内的任何小写字母。 |
[^] | ^与[]搭配是反向匹配。匹配未包含的字符,例如[^abc] 匹配非abc的字符,还能反向范围[^a-b] |
\n | 换行符匹配 |
\f | 换页符匹配 |
\r | 匹配一个回车符 |
\v | 垂直制表符匹配 |
\ | 转义符,标记下一个字符标记为特殊字符 |
如上是基础的字符匹配,为了简化表达式,又就行了一些常用的匹配做了扩展,于是有了
字符 | 说明 |
---|---|
\d | 匹配数字,等效于[0-9] |
\D | 匹配非数字,等效与[^0-9] |
\w | 匹配任何字类字符,包括下划线。等效[A-Za-z0-9_] |
\W | 与任何非单词字符匹配。与[^A-Za-z0-9_] 等效。可以用来找符号。 |
\s | 匹配任何空白字符,包括空格、制表符、换页符等。与 [ \f\n\r\t\v] 等效。 |
\S | 匹配任何非空白字符。与 [^\f\n\r\t\v] 等效。 |
一个匹配符一次只能匹配一个符号,那么要匹配多少个也需要指定,也就是限定符。
字符 | 说明 |
---|---|
{n} | n是正整数,代表着正好匹配n次,例如a{3} 匹配到的是aaa, aa匹配不到 |
{n,} | n是正整数,代表匹配n或者n次以上, |
{n,m} | n和m是正整数且n <= m,代表着匹配至少n次,最多m次 |
* | 零次或多次匹配。例如,zo* 匹配"z"和"zoo"。* 等效于 {0,}。 |
+ | 一次或多次匹配前面的字符或子表达式。例如,"zo+"与"zo"和"zoo"匹配,但与"z"不匹配。+ 等效于 {1,}。 |
? | 零次或一次匹配前面的字符或子表达式。例如,"do(es)?“匹配"do"或"does"中的"do”。? 等效于 {0,1}。 |
??或者+? | 当此字符(? )在任意限定符的后面时,它的作用不再是限定符了,而是将匹配模式换成”非贪心“,这种模式是将匹配到的字符尽可能的短。例如o+ 在oooooo匹配到的是全部,使用o{2,}? 则会只匹配到前两个o |
在一串字符中,可以规定从哪里开始匹配,比如开头,或者结尾
字符 | 说明 |
---|---|
^ | 匹配字符的开始位置 |
$ | 匹配字符的结束位置 |
\b | 匹配一个字边界,代表单词的开头或者结尾,单词之间由标点符号或者空格来分隔,但\b不会认为用逗号分割的为边界。需要配合匹配符来使用例如:\ba 匹配开头的a; [1-9]\b 以数字结尾的 |
\B | 匹配非边界字符。 |
正则表达式从左开始运算,并遵循优先级顺序,和算数表达式类似。优先级如下,高到低
字符 | 描述 |
---|---|
\ | 转义符 |
(),[],(? | 圆括号和方括号 |
*,+,?,{} | 限定符 |
^,$,\普通字符 ,普通字符 |
定位符和匹配符 |
| | 或者 |
正则表达式的标记用于指定额外的匹配策略。
//Java写法如下,其他的不知道
Pattern pattern = Pattern.compile("(?i)Java");
字符 | 描述 |
---|---|
i | ignore的缩写,代表不区分大小写 |
g | global的缩写,代表全局匹配 |
m | multi line 多行匹配 |
s | . 匹配所有单个字符除\r 和\n ,使用s则可以匹配\n |
java.util.regex是一个用正则表达式对字符串就行匹配工作的类库包,它包括了两个类:Pattern和Matcher。
Pattern类用于创建一个正则表达式,也可以说是创建一个匹配模式
静态方法创建Pattern对象,regex为正则表达式
Pattern pattern = Pattern.compile("Java");
// 返回此模式的正则表达式即Java
System.out.println(pattern.pattern());
静态方法创建Pattern对象,regex为正则表达式,flags为可选模式,如:Pattern.CASE_INSENSITIVE 忽略大小写;Pattern.DOTALL此模式下 .
会匹配换行符,默认匹配模式下 .
不会匹配换行符。等等,具体可参照Pattern的多种匹配模式。
Pattern pattern = Pattern.compile("Java", Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher("java");
//返回true,如果使用默认匹配规则则为false
System.out.println(matcher.matches());
参数 | 说明 |
---|---|
Pattern.CASE_INSENSITIVE | 忽略大小写 |
Pattern.DOTALL | . 匹配所有单个字符除\r 和\n ,使用s则可以匹配\n |
Pattern.MULTILINE | 开启多行匹配,^ $在默认的情况下只会匹配第一行,设置了MULTILINE模式回匹配所有行。 |
静态方法,判断input 是否匹配给定的正则表达式,注意的是该方法适合用于只匹配一次,且匹配全部字符串。
//返回true
Pattern.matches("\\d+","2223");
//返回false,需要匹配到所有字符串才能返回true,这里aa不能匹配到
Pattern.matches("\\d+","2223aa");
用于分隔字符串,并返回一个String[]
Pattern compile = Pattern.compile("\\d+");
//abc,def,g
String[] strArray = compile.split("abc1231def3g");
匹配器,对正则表达式的分组支持,以及对正则表达式的多次匹配支持,需要调用 Pattern 对象的 matcher 方法来获得一个 Matcher 对象。
整个字符进行匹配,只有整个字符序列完全匹配成功才返回true。
Pattern compile = Pattern.compile("\\d*");
Matcher matcher = compile.matcher("123a");
boolean status = matcher.matches();
在调用匹配方法时,会移动指针到匹配词所在字符的索引,默认是在0位置上,start为初始索引,end为所在的索引之后的一个偏移量。
Pattern pattern = Pattern.compile("\\d+");
Matcher matcher = pattern.matcher("123dfdf3424r");
boolean status = matcher.find();
if (status){
// 0
System.out.println(matcher.start());
// 3
System.out.println(matcher.end());
}
部分匹配,从第一个字符进行匹配,符合返回true并且不再继续匹配,失败了也不再继续匹配直接返回false。
Pattern compile1 = Pattern.compile("\\d");
//返回true
Matcher matcher1 = compile1.matcher("123");
//返回false
Matcher matcher2 = compile1.matcher("d123");
//返回false
Pattern compile2 = Pattern.compile("\\d{1,3}");
Matcher matcher = compile.matcher("ddds123");
//返回false
Pattern compile = Pattern.compile("\\d{1,3}");
Matcher matcher = compile.matcher("ddds123");
部分匹配,从当前位置开始匹配,找到一个匹配的子串,将移动下次匹配的位置。也可以使用find(int start)方法,从指定位置开始匹配
前面调用匹配方法,指针会移动,使用reset()将指针重置为0
返回该正则表达式中的子序列,就是以()圈起来的表达式数量,不是计算匹配数
Pattern compile = Pattern.compile("(\\d[abc])a(\\d([a]3))");
Matcher matcher = compile.matcher("123abc45b6");
//这里可以简化成()(()),总共有三对口括号,所以为3
System.out.println("找到-->"+matcher.groupCount());
当匹配到一串字符的时候,它可能是由多个子序列匹配构成的,使用grop()是获取到完整匹配字符,grop(0)等同与grop(),grop(int grop)是获取指定子序列匹配的字符
String line = "123ra9040";
String pattern = "(\\d+)([a-z]+)(\\d+)";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(line);
while (m.find( )) {
//获取完整的匹配字符->123ra9040
System.out.println("Found value: " + m.group(0) );
//获取(\\d+)匹配到->123
System.out.println("Found value: " + m.group(1) );
//获取([a-z]+)匹配到->ra
System.out.println("Found value: " + m.group(2) );
//获取
System.out.println("Found value: " + m.group(3) );
}
括号嵌套先找范围小的括号,如下:
Pattern compile = Pattern.compile("((\\d[abc])b)");
Matcher matcher = compile.matcher("123abc45b6");
while (matcher.find()){
//3ab
System.out.println(matcher.group());
//((\\d[abc])b) 3ab
System.out.println(matcher.group(1));
// (\\d[abc]) 3a
System.out.println(matcher.group(2));
}
grop(int grop) 中,grop范围可以使用groupCount()方法来确定子序列个数
#纯数字
^[0-9]*$
#n位数字
^\d{n}$
#只能输入汉字
^[\u4e00-\u9fa5]{0,}$
#邮箱
\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
# 匹配网址URL的正则表达式
[a-zA-z]+://[^\s]*
# 手机号
/^1(3\d|4[5-9]|5[0-35-9]|6[567]|7[0-8]|8\d|9[0-35-9])\d{8}$/
https://blog.csdn.net/weixin_43501172/article/details/115655288
## 匹配模式
https://blog.csdn.net/BaymaxCS/article/details/119281231
https://www.cnblogs.com/54chensongxia/archive/2020/12/16/14145325.html
https://www.runoob.com/regexp/regexp-syntax.html