正则表达式语法
1.标准字符
-
能够与‘多种字符’匹配的表达式
-
注意区分大小写,大写是相反的意思
表达式 | 描述 |
---|---|
\d | 任意一个数字,0~9中的任意一个 |
\w | 任意一个字母或数字或下划线,也就是A-Z,a-z,0-9,_中任意一个 |
\s | 包括空格、制表符、换行符等空白字符的其中任意一个 |
. | 可以匹配任意一个字符(除了换行符) 如果要匹配包括“\n"在内的所有字符,一般用[\s\S] |
2.自定义字符
[ ]方括号匹配方式,能够匹配方括号中的任意一个字符
[abc] abc之间的关系是‘或’的关系
表达式 | 描述 |
---|---|
[ABC] | 匹配 […] 中的所有字符,例如 [aeiou] 匹配字符串 “google runoob taobao” 中所有的 a e i o u 字母。 |
[^ABC] | 匹配除了 […] 中字符的所有字符,例如 [^aeiou] 匹配字符串 “google runoob taobao” 中除了a e i o u 字母的所有字母。 |
[A-Z] | [A-Z] 表示一个区间,匹配所有大写字母,[a-z] 表示所有小写字母。 |
[\s\S] | 匹配所有。\s 是匹配所有空白符,包括换行,\S 非空白符,不包括换行。 |
注意:正则表达式的特殊符号,被包含到中括号中,则失去特殊意义,除了^,-之外。
标准字符集合,除小数点外,如果被包含于中括号,自定义字符集合将包含该集合。
比如∶[ \d. \ - +] 将匹配︰数字、小数点、+、-
3.量词
修饰匹配次数的特殊符号
表达式 | 描述 |
---|---|
{n} | 表达式重复n次 |
{m,n} | 表达式至少重复m次,最多重复n次 |
{m,} | 表达式至少重复m次 |
? | 匹配表达式0次或者1次,相当于{0,1} |
+ | 表达式至少出现1次,相当于{1,} |
* | 表达式不出现或出现任意次,相当于{0,} |
匹配次数中的贪婪模式(匹配字符越多越好,默认!)
匹配次数中的非贪婪模式(匹配字符越少越好,修饰匹配次数的特殊符号后再加上一个“?”号)
例如:
/*
\d{6} 重复6次匹配数字(匹配6位数)
\d\d{6} 重复7次匹配数字(匹配7位数)
(\d\d){6} 重复12次匹配数字(匹配12位数)
\d{3,} 至少匹配三位数
\d{3,6} 最少3次最多6次匹配数字(默认贪婪模式,越多越好,优先匹配6位)
\d{3,6}? 最少3次最多6次匹配数字(非贪婪模式,越少越好,优先匹配3位)
a\d?b 匹配ab,a4b,a1b(a和b之间可以有0-1个数字)
a\d+b 匹配a1b,a22b,a333b(a和b之间至少有一个数字)
a\d*b 匹配ab,a1b,a22b,a333b(a和b之间可以有任意个数字)
*/
4.字符边界
(本组标记匹配的不是字符而是位置,符合某种条件的位置)
字符 | 描述 |
---|---|
^ | 与字符串开始的地方匹配 |
$ | 与字符串结束的地方匹配 |
\b | 匹配一个单词边界 |
\b匹配这样一个位置︰前面的字符和后面的字符不全是\w
5.选择符和分组
表达式 | 描述 |
---|---|
| | 左右两边表达式之间"或"关系,匹配左边或者右边 |
()捕获组 | 1).在被修饰匹配次数的时候,括号中的表达式可以作为整体被修饰捕获组 ; 2).取匹配结果的时候,括号中的表达式匹配到的内容可以被单独得到 ; 3).每一对括号会分配一个编号,使用()的捕获根据左括号的顺序从1开始自动编号。捕获元素编号为零的第一个捕获是由整个正则表达式模式匹配的文本 |
(?:Expression) | 一些表达式中,不得不使用(),但又不需要保存()中子表达式匹配非捕获组配的内容,这时可以用非捕获组来抵消使用()带来的副作用。 |
反向引用(\nnn )
每一对()会分配一个编号,使用()的捕获根据左括号的顺序从1开始自动编号。-通过反向引用,可以对分组已捕获的字符串进行引用。
/*
a|b 匹配a或b
([a-z]{2})\1 把原有捕获组([a-z]{2})匹配的字符再重复一遍进行匹配,如haha,gege
注意:(?:[a-z]{2})\1是匹配不到数据的
*/
6.预搜索
表达式 | 描述 |
---|---|
(?=exp) | 断言自身出现的位置的后面能匹配表达式exp |
(?!exp) | 断言此位置的后面不能匹配表达式exp |
/*
a34b asdf1 23qwer 12cedc1
[a-z]+(?=\d+) 匹配字母后面含有数字的字母(不包含数字)a,asdf,cedc
[a-z]+(?!\d+) 匹配字母后面不能还有数字的字母(不包含数字前的第一个字母)b,asd,qwer,cde
*/
常用正则表达式
1.校验数字的表达式
/*
1. 数字:^[0-9]*$
2. n位的数字:^\d{n}$
3. 至少n位的数字:^\d{n,}$
4. m-n位的数字:^\d{m,n}$
5. 零和非零开头的数字:^(0|[1-9][0-9]*)$
6. 非零开头的最多带两位小数的数字:^([1-9][0-9]*)+(.[0-9]{1,2})?$
7. 带1-2位小数的正数或负数:^(\-)?\d+(\.\d{1,2})?$
8. 正数、负数、和小数:^(\-|\+)?\d+(\.\d+)?$
9. 有两位小数的正实数:^[0-9]+(.[0-9]{2})?$
10. 有1~3位小数的正实数:^[0-9]+(.[0-9]{1,3})?$
11. 非零的正整数:^[1-9]\d*$ 或 ^([1-9][0-9]*){1,3}$ 或 ^\+?[1-9][0-9]*$
12. 非零的负整数:^\-[1-9][]0-9"*$ 或 ^-[1-9]\d*$
13. 非负整数:^\d+$ 或 ^[1-9]\d*|0$
14. 非正整数:^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$
15. 非负浮点数:^\d+(\.\d+)?$ 或 ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$
16. 非正浮点数:^((-\d+(\.\d+)?)|(0+(\.0+)?))$ 或 ^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$
17. 正浮点数:^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ 或 ^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$
18. 负浮点数:^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ 或 ^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$
19. 浮点数:^(-?\d+)(\.\d+)?$ 或 ^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$
*/
2.校验字符的表达式
/*
1. 汉字:^[\u4e00-\u9fa5]{0,}$
2. 英文和数字:^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$
3. 长度为3-20的所有字符:^.{3,20}$
4. 由26个英文字母组成的字符串:^[A-Za-z]+$
5. 由26个大写英文字母组成的字符串:^[A-Z]+$
6. 由26个小写英文字母组成的字符串:^[a-z]+$
7. 由数字和26个英文字母组成的字符串:^[A-Za-z0-9]+$
8. 由数字、26个英文字母或者下划线组成的字符串:^\w+$ 或 ^\w{3,20}$
9. 中文、英文、数字包括下划线:^[\u4E00-\u9FA5A-Za-z0-9_]+$
10. 中文、英文、数字但不包括下划线等符号:^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$
11. 可以输入含有^%&',;=?$\"等字符:[^%&',;=?$\x22]+
12. 禁止输入含有~的字符:[^~\x22]+
*/
3.特殊需求表达式
/*
1. Email地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
2. 域名:[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?
3. InternetURL:[a-zA-z]+://[^\s]* 或 ^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$
4. 手机号码:^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$
5. 电话号码("XXX-XXXXXXX"、"XXXX-XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX):^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$
6. 国内电话号码(0511-4405222、021-87888822):\d{3}-\d{8}|\d{4}-\d{7}
7. 身份证号(15位、18位数字):^\d{15}|\d{18}$
8. 短身份证号码(数字、字母x结尾):^([0-9]){7,18}(x|X)?$ 或 ^\d{8,18}|[0-9x]{8,18}|[0-9X]{8,18}?$
9. 帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
10. 密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线):^[a-zA-Z]\w{5,17}$
11. 强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间):^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$
12. 日期格式:^\d{4}-\d{1,2}-\d{1,2}
13. 一年的12个月(01~09和1~12):^(0?[1-9]|1[0-2])$
14. 一个月的31天(01~09和1~31):^((0?[1-9])|((1|2)[0-9])|30|31)$
*/
Java编程中使用正则表达式
在Java中使用正则表达式,首先得知道两个类,一个叫做Pattern,一个叫做Matcher,这两个类都是java.util.regex包下的
Pattern类
可以把它简单理解为就是一个正则表达式(就像File类一样,我们可以简单理解为它就是一个文件)。Pattern类没有公共的构造方法,这意味着我们不能直接new一个Pattern类的对象。在这个类中,提供了一个方法,名字叫compile,我们将正则表达式作为参数,传入这个方法中,就可以得到一个Pattern对象,我们可以将这个对象理解为就是传入的正则表达式。
Pattern类有一个实例方法,叫做matcher,这个方法接收一个参数,就是需要匹配的字符串,方法的返回值就是一个Mather对象。
Matcher类
一个Matcher对象就是一个匹配器,我们通过这个匹配器,就可以操作正则表达式与字符串的匹配过程。操作的是哪个正则表达式和字符串呢?就是我们调用Pettern类的compile方法生成的Pettern对象,以及调用Pettern对象的matcher方法传入的要匹配的字符串。通过这个匹配器对象,我们可以控制字符串的匹配,查看匹配结果,甚至可以替换等便利的操作。
1.匹配正则表达式
package com.stx.regularexpression;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Demo01 {
public static void main(String[] args) {
// 使用Pattern类的compile方法,传入一个正则表达式(若有\则要多写一个\),得到一个Pattern对象
Pattern pattern = Pattern.compile("\\w+");
// 调用pattern对象的matcher方法,传入需要匹配的字符串,得到一个匹配器对象
Matcher matcher = pattern.matcher("$$as_df&*%12qww3##8");
/*
find方法的作用就是尝试从字符串中找到下一个匹配正则表达式的部分,
若匹配成功,就返回true,否则返回false,而已经匹配的部分会被跳过
*/
while (matcher.find()) {
// start()方法返回上一次匹配部分的开始索引
System.out.print(matcher.group() + "\t");
// end()方法返回上一次匹配部分的结束索引+1的值
System.out.println(matcher.start() + "-->" + (matcher.end() - 1));
}
}
}
执行结果:
as_df 2-->6
12qww3 10-->15
8 18-->18
2.正则表达式中分组的处理
package com.stx.regularexpression;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Demo02 {
public static void main(String[] args) {
Pattern pattern = Pattern.compile("([a-z]+)([0-9]+)");
Matcher matcher = pattern.matcher("abc123%fqqed8*654tgb111");
while (matcher.find()) {
System.out.println(matcher.group());// group(),group(0)都是返回匹配整个表达式的字符串
System.out.print(matcher.group(1) + "\t");// 返回group()中符合第一个捕获组的字符串([a-z]+)
System.out.println(matcher.group(2));// 返回group()中符合第二个捕获组的字符串([0-9]+)
System.out.println("************");
}
}
}
执行结果:
abc123
abc 123
************
fqqed8
fqqed 8
************
tgb111
tgb 111
************
3.通过正则对象分割字符串
package com.stx.regularexpression;
import java.util.Arrays;
import java.util.regex.Pattern;
public class Demo03 {
public static void main(String[] args) {
// 按任意个数字分割字符串
String str = "qwer123asdf988zxcvb5678tttt5a";
Pattern pattern = Pattern.compile("[0-9]+");
String[] strs = pattern.split(str);
//String[] strs = str.split("[0-9]+");
System.out.println(Arrays.toString(strs));
}
}
执行结果:
[qwer, asdf, zxcvb, tttt, a]
4.通过正则对象替换字符串
package com.stx.regularexpression;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Demo04 {
public static void main(String[] args) {
Pattern pattern = Pattern.compile("[0-9]");
Matcher matcher = pattern.matcher("123$$as_d88f&%12qww3##8");
String str = matcher.replaceAll("*");// 将字符串中所有的数字替换成*
System.out.println(str);
}
}
执行结果:
***$$as_d**f&%**qww*##*