目录
1. 概念
正则表达式是一种可以用于模式匹配和替换的规范。
一个正则表达式就是由普通字符,以及特殊字符(12个元字符)组成的文字模式。
用以描述在查找文字主体时待匹配的一个或多个字符串。
正则表达式作为一个模版,将某个字符模式与所搜索的字符串进行匹配。
2. 用途
字符串匹配(字符匹配)
字符串查找
字符串替换
字符串分割
3. 元字符
^:匹配输入字符串的开始位置。如果在方括号表达式中使用,则表示不接受该字符集合
$:匹配输入字符串的结尾位置。
():标记一个子表达式(捕获组)的开始和结束位置。
*:匹配前面的子表达式零次或多次。
+:匹配前面的子表达式一次或多次。
?:匹配前面的子表达式零次或一次,或指明一个非贪婪限定符(JMeter正则提取器中用到)。
.:匹配除换行符\n之外的任何单字符。
\:转义,将下一个字符标记为特殊字符,或原义字符,或向后引用,或八进制转义符。
[:标记一个中括号表达式的开始。
{:标记限定符表达式的开始。
|:指明两项之间的一个选择。
4. 预定义字符类
\t:制表符,等同 /u0009
\n:换行符,等同 /u000A
\d:代表一个数字,等同于 [0-9]
\D:代表非数字,等同于[^0-9]
\s:代表换行符,Tab制表符等空白符
\S:代表非空白字符
\w:代表字母字符,等同于[a-zA-Z_0-9]
\W:代表非字母字符,等同于 [^/w]
5. 量词
当要匹配的正则表达式里有一部分重复多次时,可以用量词来进行匹配固定或不定次数的重复。
X?:零次或一次
X*:零次或多次
X+:一次或多次
X{n}:恰好n次
X{n,}:至少n次
X{n,m}:至少n次,但不超过m次
6. 常用类:Pattern,Matcher
示例:
Pattern p= Pattern.compile("a*b"); //a*b是被编译的正则表达式
Matcher m = p.matcher("aaaaab"); //aaaaab是待匹配的表达式
boolean b = m.matches(); //b是匹配结果,返回boolean
等价于:
boolean b = Pattern.matches("a*b", "aaaaab");
注意:
Matcher类中的matches()方式进行完全匹配。find()方法进行部分匹配。
(1)matches !!!
作用:编译给定正则表达式,并尝试将给定输入与其匹配。
语法:public static boolean matches(String regex, CharSequence input)
抛出异常:PatternSyntaxException - 如果表达式的语法无效
使用:
方式一:Pattern.matches(regex, input);
方式二:Pattern.compile(regex).matcher(input).matches() ;
如果要多次使用一种模式,编译一次后重用此模式比每次都调用此方法效率更高。
参数:
regex - 要编译的表达式
input - 要匹配的字符序列
补充:
String类中的matches()方法是调用Pattern类中的matches()方法。
String类中的contains()方法也可以判断一个字符串中是否包含某个子串。
(2)find!!!
作用:此方法从匹配器区域的开头开始,如果该方法的前一次调用成功了,并且从那时开始匹配器没有被重置,则从以前一次匹配操作没有匹配的第一个字符开始,继续往下匹配。
语法:public boolean find() //尝试查找与该模式匹配的输入序列的下一个子序列。
说明:
如果匹配成功,则可以通过 start、end 和 group 方法获取更多信息。
matcher.start() :返回匹配到的子字符串在字符串中的索引位置。
matcher.end() :返回匹配到的子字符串的最后一个字符在字符串中的索引位置。
matcher.group() :返回匹配到的子字符串。
返回:当且仅当输入序列的子序列匹配此匹配器的模式时才返回 true。
示例:
package com.my.demo;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class GroupDemo {
public static void main(String[] args) {
Pattern p = Pattern.compile("^[A-Z][a-zA-Z0-9_]{5,15}$"); //正则表达式
String ma="Sheryl666"; //要匹配的字符串
Matcher m = p.matcher(ma);
boolean b = m.matches(); //b为匹配结果,boolean值
System.out.println(b);
}
}
运行结果:
true
Process finished with exit code 0
7. 捕获组group()
(1)定义:
捕获组group是以括号对"()"分割出的子Pattern,有几个括号就表示有几个组。
在JAVA中使用正则表达式返回符合正则表达式的字符串,就要用到group()。
group中记录了所有符合指定表达式的字符串。
(2)说明:
表达式((A)(B(C))中,存在四个组:
0组:表示整个表达式
1组:表示((A)(B(C)))
2组:表示 (A)
3组:表示(B(C))
4组:表示(C)
示例1:
public class GroupDemo {
public static void main(String[] args) {
Pattern p = Pattern.compile("(\\d+,)(\\d+)"); //首先创建Pattern对象,在其中编译要用到的表达式
String s = "123,456-34,345";
Matcher m = p.matcher(s); //接着使用matcher方法在字符串中匹配指定表达式
//输出查找结果了,在调用m.group之前,一定要记着调用m.find,不然会产生编译错误
//在正则表达式中,用括号括起来的算作一组
//group(0)于group()等价,表示整个正则表达式的匹配字符串,可能有多个匹配结果,通过循环逐个打印
//group(1)等价于第一个括号内的表达式返回的字符串,以此类推
//当while循环执行过一轮,第二轮就输出第二组匹配的字符串
while(m.find()) {
System.out.println("m.group():" + m.group()); //打印一个完整的匹配结果
System.out.println("m.group(1):" + m.group(1)); //打印第一个(\d+,)
System.out.println("m.group(2):" + m.group(2)); //打印第二个(\d+)
System.out.println("*********************");
}
System.out.println("捕获个数:groupCount()="+m.groupCount());
}
}
运行结果:
m.group():123,456
m.group(1):123,
m.group(2):456
*********************
m.group():34,345
m.group(1):34,
m.group(2):345
*********************
捕获个数:groupCount()=2Process finished with exit code 0
解析:
1)首先创建Pattern对象,在其中编译要用到的表达式。
2)接着使用matcher方法在字符串中匹配指定表达式。
3)然后输出查找结果了,在调用m.group之前一定要记着调用m.find(find()方法返回布尔值,即是否有找到一个符合正则表达式的字符串)。不然会产生编译错误。
4)在正则表达式中,用括号括起来的算作一组,group(0)和group()等价,表示整个正则表达式的匹配字符串(注意:这里是指匹配到的实际字符串,不是正则表达式),group(1)等价于第一个括号内的表达式返回的字符串,以此类推。
当while循环执行过一轮,第二轮就输出第二组可以整个匹配的字符串。
示例2:
public class GroupDemo {
public static void main(String[] args) {
String str = "aabcdfabchhhbckkkaaabcc";
Pattern p = Pattern.compile("(((a+)b)c)");
Matcher m = p.matcher(str);
while(m.find()) {
System.out.println(m.start());
System.out.println(m.end());
System.out.println(m.group());
System.out.println("*********************");
}
}
}
运行结果:
0
4
aabc
*********************
6
9
abc
*********************
17
22
aaabc
*********************Process finished with exit code 0
8. 非捕获组
定义:以?开头的组是纯的非捕获组,它不捕获文本,也不针对组合进行计数。
即,如果小括号中以?开头,那么这个分组就不会捕获文本,当然也不会有组的编号。
(?=X):仅当子表达式X在此位置的右侧匹配时才能继续匹配
(?!X):仅当子表达式X不在此位置的右侧匹配时才能继续匹配
( ?<=X):仅当子表达式X在此位置的左侧匹配时才继续匹配
(?<!X):仅当子表达式X不在此位置的左侧匹配时才能继续匹配
举例:
(?<!4)56(?=9)这里就是匹配后面的文本56前面不能是4,后面必须是9组成的。
9. 贪婪匹配与非贪婪匹配
贪婪匹配:正则表达式一般趋向于最大长度匹配
非贪婪匹配:匹配到结果就好,最少的匹配字符
默认是贪婪模式,在量词后面加上一个?就是非贪婪模式。
10. 补充
(1)正则的api在java.util.regex里。一般我们需要的api, 都在rt.jar里。
(2)用得最多的就是 . * +
(3)待核实的问题:matcher里的matches 方法和 find方法,用一次mathes之后,要用find,需要重新设置matcher?