第十二天
正则表达式
1.正则表达式简介
-
正则表达式(Regular Expressions),是一个特殊的字符串,可以对普通的字符串进行校验检测等工作。正则表达式不是Java特有的,它是一套独立的语法,可以在java,c++,python等语言中使用。
-
正则表达式,最基本的使用场景是用来做校验,校验一个字符串是否满足预设的规则。在校验的基础 上,又添加了若干个其他的引用场景,例如: 批量的查找、替换、切割...
2.正则表达式语法
-
字符串中常用方法
方法名以及返回值类型 | 解析 |
---|---|
boolean matches(String regex) | 判断this字符串是否匹配正则表达式regex |
String[] split(String regex) | 对this使用匹配上正则表达式的子串进行切分成字符串数组 |
replaceAll(String regex, String replacement) | 将一个字符串中的所有的满足正则规则部分的字符串,替换成指定的字符串 |
replaceFirst(String regex, String replacement) | 将一个字符串中的第一个满足正则规则部分的字符串,替换成指定的字符串 |
-
字符集语法
表达式 | 解析 |
---|---|
[] | 表示匹配括号里的任意一个字符。 |
[abc] | 字符集。匹配a 或者 b 或者 c |
[^abc] | 反向字符集。 |
[a-g] | 字符范围。表示匹配所有的小写字母的任意一个。 |
[^a-z] | 反向字符范围。匹配不在指定的范围内的任何字符。例如,"a-z"匹配任何不在"a"到"z"范围内的任何字符。 |
[A-Za-z] | 表示匹配所有的小写字母和大写字母的任意一个。 |
[a-zA-Z0-9] | 表示匹配所有的小写字母和大写字母和数字的任意一个。 |
[a-z&&bc] | 表示匹配所有的小写字母除了b和c, 只要匹配上就是true. |
\d | 用于匹配数字字符中的任意一个 相当于[0-9] |
\D | 用于匹配非数字字符中的任意一个 相当于0-9 |
\w | 匹配单词字符中的任意一个 单词字符就是[a-zA-Z0-9_] |
\W | 用于匹配非单词字符中的任意一个 |
\s | 用于匹配空格,制表符,退格符,换行符等中的任意一个 |
\S | 用于匹配非空格,制表符,退格符,换行符等中的任意一个 |
. | 用于匹配任意一个字符 |
-
量词语法
X? | 匹配0个或1个 |
---|---|
X* | 匹配0个或1个以上 |
x+ | 匹配1个以上 |
X{n} | 匹配n个 |
X{m,} | 匹配m个以上 |
X{m,n} | 匹配m~n个 |
-
分组语法
() | 在正则表达式上可以使用()来进行对一些字符分组,并可以使用逻辑运算符|来进行选择匹配 |
---|---|
-
^和$
^ | 表示严格从头匹配 |
---|---|
$ | 表示匹配到结尾 |
3.Pattern的简介
其实,Pattern这个类,才是真正来操作正则表达式的类,它位于java.util.regex包下。在String类中的提供的 matches 、split 、replace等方 法,其实都是对这个类中的某些方法的封装。
在我们调用String类中的提供的 matches 、split 、replace等方法时,底层就会创建一个Pattern对象。这样的做法效率是很低的。我们何不主动创建一个pattern,然后每次需要匹配就直接用它而不需要再次创建,大大提高了程序的效率。
static Pattern complie(String regex)
Pattern类的构造方法是私有的,不可以直接创建,但可以通过Pattern.complie(String regex)简单工厂方法创建一个正则表达式,
如:
Pattern p=Pattern.compile("\\w+");
2.pattern()
返回正则表达式的字符串形式,其实就是返回Pattern.complile(String regex)的regex参数
Pattern p=Pattern.compile("\\w+"); String regex = p.pattern();//返回 \w+
3.matcher(String str**)**
返回一个Matcher类型的对象。
Matcher matcher = p.matcher("michael");
4.Matcher类
Pattern类只能做一些简单的匹配操作,要想得到更强更便捷的正则匹配操作,那就需要将Pattern与Matcher一起合作.Matcher类提供了对正则表达式的分组支持,以及对正则表达式的多次匹配支持。简单来说,Matcher对象就是Pattern对象与字符串匹配的一个结果。
4.1 Matcher对象的获取
Matcher的构造方法是私有的,我们一般通过调用Pattern对象的matcher方法返回一个matcher。
String info = "名字:wulei 地址:hunan 电话:010-82350555"; Pattern p = Pattern.compile("(名字:\\w+\\s+)|(地址:\\w+\\s+)|(电话:\\d{3}-\\d{8})"); Matcher matcher = p.matcher(info);
4.2 Matcher类型的匹配方法
Matcher对象提供了三个不同的匹配方式:matches、 lookingAt()、find()。三个方法均返回boolean类型,当匹配到时返回true,没匹配到则返回false
-
boolean matches()
-
整个字符串必须符合正则表达式,才会返回true,否则返回false
-
String info = "123abc"; Pattern p = Pattern.compile("\\d+"); Pattern p1 = Pattern.compile("\\d+\\w+"); Matcher matcher = p.matcher(info); Matcher matcher1 = p1.matcher(info); System.out.println(matcher.matches());//false System.out.println(matcher1.matches());//true
-
-
boolean lookingAt()
-
字符串的开头符合使用的正则表达式,返回true。否则返回false。
-
System.out.println(matcher.lookingAt()); //true、
-
-
boolean find()
-
对字符串进行匹配,匹配到的子串可以在任何位置.。每次调用它,matcher里面的匹配指针都会向后移。
-
Pattern p=Pattern.compile("\\d+"); Matcher m=p.matcher("22bb23"); m.find();//返回true Matcher m2=p.matcher("aa2223"); m2.find();//返回true Matcher m3=p.matcher("aa2223bb"); m3.find();//返回true Matcher m4=p.matcher("aabb"); m4.find();//返回false
-
String info = "123abc456def789"; Pattern p = Pattern.compile("\\d+"); Matcher matcher = p.matcher(info); while(matcher.find()){ System.out.println(matcher.group()); } 输出: 123 456 789
-
-
reset()
-
重置find()的指针。注意:lookingAt()会影响到find()查找的子字符串
-
String info = "123abc456def789"; Pattern p = Pattern.compile("\\d+"); Matcher matcher = p.matcher(info); System.out.println("执行lookingAt()后的group:"); matcher.lookingAt(); System.out.println(matcher.group()); //matcher.reset(); System.out.println("执行find():"); while(matcher.find()){ System.out.println(matcher.group()); } 输出: 执行lookingAt()后的group: 123 执行find(): 456 789
-
4.3 Matcher类型的详情方法
当我们执行完匹配操作后,我们常常需要获得匹配到的具体字符串。matcher对象能够使用group()、start()、end()方法来获取相关信息。
注意:这三个方法是基于我们matcher执行matches()|lookingAt()|find()并匹配成功的情况下才能使用,否则会抛出java.lang.IllegalStateException
-
group()
-
返回匹配到的子字符串
-
-
group(int index)
-
返回匹配到的子字符串里的第index个分组,group(0)=group()。
-
-
start()
-
返回匹配到的子字符串在字符串中的索引位置
-
-
start(int index)
-
返回匹配到的子字符串里的第index个分组开始的索引。
-
-
end()
-
返回匹配到的子字符串的最后一个字符在字符串中的索引位置+1
-
-
end(int index)
-
返回匹配到的子字符串里的第index个分组结束的索引+1。
-
String info = "123abc456def789"; Pattern p = Pattern.compile("(\\d+)([a-z]+)"); Matcher matcher = p.matcher(info); while (matcher.find()){ System.out.println("start(1): " + matcher.start(1)); System.out.println("start(2): " + matcher.start(2)); System.out.println("end(1): " + matcher.end(1)); System.out.println("end(2): " + matcher.end(2)); } 输出: start(1): 0 start(2): 3 end(1): 3 end(2): 6 start(1): 6 start(2): 9 end(1): 9 end(2): 12
-
现在我们使用一下稍微高级点的正则匹配操作,例如有一段文本,里面有很多数字,而且这些数字是分开的,我们现在要将文本中所有数字都取出来,利用java的正则操作是那么的简单.
-
Pattern p=Pattern.compile("\\d+"); Matcher m=p.matcher("我的QQ是:456456 我的电话是:0532214 我的邮箱是:aaa123@aaa.com"); while(m.find()) { System.out.println(m.group()); } 输出: 456456 0532214 123 如将以上while()循环替换成 while(m.find()) { System.out.println(m.group()); System.out.print("start:"+m.start()); System.out.println(" end:"+m.end()); } 则输出: 456456 start:6 end:12 0532214 start:19 end:26 123 start:36 end:39
-
-
int groupCount()
-
用于获取正则表达式中的小括号的个数。() 用于分组。
-
import java.util.regex.Matcher; import java.util.regex.Pattern; /** * 研究一下groupCount(): */ public class PatternDemo07Matcher05 { public static void main(String[] args) { Pattern pattern = Pattern.compile("(((c)a)(t))s"); Matcher matcher = pattern.matcher("one cat, two cats in the yard"); /** * int groupCount(): * 作用:用于获取正则表达式中的小括号的个数。() 用于分组。 */ System.out.println(matcher.groupCount()); while (matcher.find()) { // 打印符合正则表达式的子串, 因此循环次数是xxxx次。 System.out.println(matcher.group()); } /** * 使用小括号的个数来循环, 可以使用group的重载方法: * String group(int group) * * 注意:想要使用()的个数进行遍历,需要将指针移动到字符串之前,然后还需要调用一下find方法 * * group(0): 表示的是对组进行拆分括号的整体的样子 * group(1): 表示第一个括号 * group(2): 表示第二个括号 */ matcher.reset(); matcher.find(); for (int i = 0; i <=matcher.groupCount(); i++) { System.out.println(matcher.group(i)); } } }
-