基本语法
正则表达式:校验字符串是否满足一定的规则,用来校验数据格式的合法性
作用:校验字符串是否满足规则,在一段文本中查询满足要求的内容。
- 使用方式(java中)
String str="123456";
str.matches("正则表达式内容");
使用规则
- 字符类型(只匹配一个字符)
表达式 | 说明 |
---|---|
[abc] | 只能是a,b,或c |
[^abc] | 除了a,b,c之外的字符 |
[a-zA-Z] | a到z,或A到Z,包括(范围) |
[a-d[m-p]] | a到d,或m到p |
[a-z&&[def]] | a-z和def的交集:def |
[a-z&&[^def]] | a-z和非def的交集:等同于:[ad-z] |
[a-z&&[^m-p]] | a到z和除了m到p的交集:等同于[a-lq-z] |
[0-9] | 只能为字符0到9 |
字符类表示比如说:
"abc"然后[abc]这个是对第一个字符a进行匹配!后面的bc如果也需要匹配就写成[abc][abc][abc]这样的形式
- 预定义字符(只匹配一个字符!)
表达式 | 说明 |
---|---|
. | 任何字符,除了\n和\r |
\d | 一个数字:相当于[0-9] |
\D | 非数字,相当于:[^0-9] |
\s | 一个空白字符:相当于[\t\n\x0B\f\r] |
\S | 非空白字符 |
\w | 相当于[a-zA-Z_0-9]英文,数字,下划线 |
\W | [^\w]一个非单词字符 |
注意:在java当中 \是代表转义字符,如果想写正则表达式需要写 \\d这种,意思就是把 \d转义成\\d
如果不写就代表把字符d转义!
- 数量词
表达式 | 说明 |
---|---|
X? | ?前面的X出现1次或者0次 |
X* | *前面的X出现0次或者多次 |
X+ | +前面的X出现1次或多次 |
X | X这个出现n次 |
X | X这个出现n次及以上 |
x | X这至少n次但不超过m次 |
小细节:X可以是单个字符也可以是一组
ab+表示的是第一个字符必须为a,第二个字符可以是b并且可以在后面出现1次或多次,这里的X代表字符
a(bc)+表示的是第一个字符必须为a,后面进行了分组,这里的X是bc,且bc在后面要出现1次或多次
- 符号
符号 | 说明 | 举例 |
---|---|---|
[] | 表示里面的内容只出现一次 | [0-9] |
() | 分组 | a(bc)+表示,bc这一组至少出现一次,等同于 abcbcbc...(bc至少出现一次) |
^ | 取反 | [^abc] |
&& | 两个范围的交集 | [a-z&&A-Z] |
| | 写在方括号外面表示并集 | x|X |
. | 任意字符 | \n回车符号不匹配! |
\ | 转义字符 | \\d |
(?i) | 忽略后面字符的大小写 | (?i)abc |
只忽略b的大小写 | a((?i)b)c |
java使用正则表达式
- Pattern:表示正则表达式类
- Matcher:文本匹配器,作用按照正则表达式的规则去读取字符串,从头开始读取
使用方法:
Pattern p=Pattern.compile("正则表达式");//获取Pattern对象
Matcher m=p.matcher(str);//str里面是文本内容,字符串格式的
//m:文本匹配器
//p:规则
//str:文本
//m要在str中找到符合p规则的小串
m.find();//拿着文本匹配器,从头开始找满足规则的字串,如果有返回true,没有返回false
//找到后会在底层记录小串的起始索引和结束索引+1,之所以+1是因为调用的是substring这个方法剪切的小串!
String s1=m.group();//这个方法会把找到的小串获取出来
//总体来写:
String str="Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11,因为这两个版本是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会登上历史的舞台";
Pattern p=Pattern.compile("java\\d{0,2}");
Matcher m=p.matcher(str);
while(m.find()){
String s=m.group();
sout(s);
}
带条件的爬取数据
String str="Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11,因为这两个版本是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会登上历史的舞台";
//需求1:爬取版本号为8,11,17的java文本,但是只要java文本不要版本号
String regex="Java(?=8|11|17)"//这里是?=
Pattern p=Pattern.compile(regex);
Matcher m=p.matchers(s);
while(m.find()){
System.out.println(m.group());
}
//需求2:爬取版本号为8,11,17的java文本,正确爬取结果为:java8,java11 java 17
String regex="Java(?:8|11|17)"//这里是?:
Pattern p=Pattern.compile(regex);
Matcher m=p.matchers(s);
while(m.find()){
System.out.println(m.group());
}
//需求3:爬取除了版本号为8,11,17的文本
String regex="Java(?!8|11|17)"//这里是!
Pattern p=Pattern.compile(regex);
Matcher m=p.matchers(s);
while(m.find()){
System.out.println(m.group());
}
Java(?=8|11|17)解释:?相当于前面的J数据ava,=代表Java后面要跟随8或11或17,但是在获取的时候只获取前半部分Java
Java(?:8|11|17)解释:?相当于前面的数据java,:代表Java后面要跟随8或11或17,并且在获取的时候后面要跟随数字8或11或17
Java(?!8|11|17)解释:?相当于前面的数据java,!代表爬取Java后面跟随的除了8或11或17的java文本
贪婪爬取和非贪婪爬取
贪婪爬取:在爬取的时候尽可能多的爬取数据
非贪婪爬取:在爬取的时候尽可能少的爬取数据
Java默认使用贪婪爬取,但是在数量词+,*后面加上?就是非贪婪爬取
String str="<h1>hello world</h1>";
//贪婪爬取
String regex="<.*>"
Pattern p=Pattern.compile(regex);
Matcher m=p.matchers(s);
while(m.find()){
System.out.println(m.group());
}
//结果:<h1>hello world</h1>
//分析:贪婪爬取<,*> 其中.*代表所有字符 <代表头部的< >代表尾部的>
//在正则表达式看来是:<h1 hello world /h1>这样的匹配形式
//非贪婪爬取
String regex="<.*?>?"
Pattern p=Pattern.compile(regex);
Matcher m=p.matchers(s);
while(m.find()){
System.out.println(m.group());
}
//结果:<h1>
// </h1>
正则表达式在字符串中的使用
- 常用的,还有其他的可以在API帮助文档中查。。。
方法名 | 说明 |
---|---|
public String[] matches(String 正则表达式) | 判断字符串是否满足正则表达式规则 |
public String replaceAll(String 正则表达,String 新字符串) | 把满足正则表达式的小串替换为新的字符串 |
public String[] split(String 正则表达式) | 把满足正则表达式的小串分割 |
捕获分组和非捕获分组
正则表达式当中,每一组都是有组号的,也就是序号。
小括号代表的就是分组
-
规则1:从1开始,连续不间断
-
规则2:以左括号为基准,最左边的是第一组,其次为第二组,依次递推
(\\d+)(\\d+)(\\d+)就代表第一组,第二组,第三组
(\\d+(\\d+))(\\d+)这里第二个\\d+是第二组!因为规则2
- 捕获分组:把这一组比如说第二组中的数据,拿出来再用依次
//判断一个字符串的开始字符和结束字符是否一致,只考虑一个字符
举例:a123a b123b 122241 &a3fsfes&
正则表达式:(.).+(.)\\1
\\1表示把第一组的数据(.)拿出来再用一次
\\X 表示把第X组的数据拿出来再用一次
//判断一个字符串的开始和结束字符是否一致,可以有多个字符
举例:abc123abc bbdb123bdbb
正则表达式:(.+).+\\1
//判断一个字符串的开始和结束部分是否一致,开始部分内部的每个字符也需要一致
举例:aaa123aaa bbb123bbb
正则表达式:((.)\\2*).+\\1*
(.)表示把首字母看做一组
//2表示把首字母拿出再次使用
*作用于\\2表示后面重复的内容出现0次或多
.+表示中间任意字符出现1次或多次
\\1表示((.)\\2*)
*表示\\1出现0次或多次
//需求:将字符串:我要学学学编编编编程程程程程程
// 替换为:我要学编程
String str="我要学学学编编编编程程程程程程";
String result=str.replaceAll("(.)\\1+","$1");
replaceAll是String自带的方法,第一个是正则表达式,第二个$1表示在正则表达式中使用第一个分组的内容
在正则表达式中调用分组用 \组号 在正则表达式外用分组是用$组号
- 非捕获分组:分组之后不需要在使用本组数据,仅仅只是把数据括起来(不占用组号)
符号 | 含义 | 举例 |
---|---|---|
(?:正则) | 获取所有 | Java(?:8|11|17) |
(?=正则) | 获取前面部分 | Java(?=8|11|17) |
(?!正则) | 获取不是指定内容的前面部分 | Java(?!8|11|17) |