正则表达基本
正则表达式是Java提供的一种专门用于字符串执行模式匹配的技术。
正则表达式:
regular expression=>RegExp
代码演示
public static void main(String[] args) {
// 定义一个字符串变量,并初始化为 "123abc"
String content = "123abc";
// 定义一个字符串变量,表示要匹配的正则表达式
// 此表达式要求字符串以至少一个数字开头,后跟任意个小写字母
String regstr = "[0-9]+[a-z]*";
// 使用 Pattern 类的 compile 方法编译正则表达式
Pattern pattern = Pattern.compile(regstr);
// 使用 Matcher 类的 matcher 方法创建匹配器对象,并将其与 content 进行匹配
Matcher matcher = pattern.matcher(content);
// 使用 while 循环遍历匹配结果
while (matcher.find()) {
// 输出匹配到的内容
System.out.println("=" + matcher.group(0));
}
}
正则表达语法
想灵活的运用正则表达式,则必须了解其各种元字符的功能,元字符从功能上大致分为:限定符、选择匹配符、分组组合和反向引用符、特殊字符、字符匹配符、定位符
转义号 \\
在正则表达式中,有一些特殊字符具有特定的含义和功能。当需要在正则表达式中使用这些特殊字符本身的字面意义时,需要使用转义符号 \\
符号 | 符号含义 |
---|---|
\\. | 匹配 . 本身 |
\\* | 匹配 * 本身 |
\\+ | 匹配 + 本身 |
\\( \\) | 匹配 () 本身 |
\\$ | 匹配 $ 本身 |
\\ / | 匹配 / 本身 |
\\ | 匹配 \ 本身,字符串中表示一个反斜杠 |
\\? | 匹配 ? 本身 |
\\[ \\] | 匹配 [ ] 本身 |
\\^ | 匹配 ^ 本身 |
\\{ \\} | 匹配 {} 本身 |
注意:在Java的正则表达式中,两个 \\ 代表其他语言中的一个 \
字符匹配
符号 | 符号含义 | 示例 | 解释 |
---|---|---|---|
[ ] | 可接收的字符列表 | [efgh] | e、f、g、h中的任意1个字符 |
[^] | 不接收的字符列表 | [ ^abc] | 除a、b、c之外的任意1个字符,包括数字和特殊符号 |
- | 连字符 | A-Z | 任意单个大写字母 |
. | 匹配除 \n 以外的任何字符 | a…b | 以a开头,b结尾,中间包括2个任意字符的长度为4的字符串 |
\\d | 匹配单个数字字符,相当于[0-9] | \\d{3}(\\d)? | 包含3个或4个数字的字符串 |
\\D | 匹配单个非数字字符,相当于 [ ^ 0-9] | \\D(\\d)* | 以单个非数字字符开头,后接任意个数字字符串 |
\\w | 匹配单个数字、大小写字母字符,相当于[0-9a-zA-Z) | \\d{3}\\w{4} | 以3个数字字符开头的长度为7的数字字母字符串 |
\\W | 匹配单个非数字、大小写字母字符,相当于[ ^0-9a-zA-Z] | \\W+\\d{2} | 以至少1个非数字字母字符开头,2个数字字符结尾的字符串 |
选择匹配符
在匹配某个字符串时需要选择,即:既可以匹配这个,又可以匹配那个,这时需
要用到选择匹配符号 |
符号 | 符号含义 | 示例 | 解释 |
---|---|---|---|
| | 匹配“|”之前或之后的表达式 | ab|cd | 匹配ab或者cd |
限定符
用于指定其前面的字符和组合项连续出现多少次
符号 | 符号含义 | 示例 | 解释 |
---|---|---|---|
* | 指定字符重复0次或n次(无要求)零到多次 | (abc)* | 仅包含任意个abc的字符串,等效于\w* |
+ | 指定字符重复1次或n次(至少一次)1到多 | m+(abc)* | 以至少1个m开头,后接任意个abc的字符串 |
? | 指定字符重复0次或1次(最多一次)0到1 | m+abc? | 以至少1个m开头,后接abc或ab的字符串 |
{n} | 只能输入n个字符 | [abcd]{3} | 匹配由abcd中字母组成的任意长度为3的字符串 |
{n,} | 指定至少n个匹配 | [abcd]{3,} | 匹配由abcd中字母组成的任意长度不小于3的字符串 |
{n,m} | 指定至少n个但不多于m个匹配 | [abcd]{3,5} | 匹配由abcd中字母组成的任意长度不小于3,不大于5的字符串 |
定位符
定位符, 规定要匹配的字符串出现的位置
符号 | 符号含义 | 示例 | 解释 |
---|---|---|---|
^ | 指定起始字符 | ^ [0-9]+[a-z]* | 以至少1个数字开头,后接任意个小写字母的字符串 |
$ | 指定结束字符 | ^ [0-9]\\-[a-z]+$ | 以1个数字开头后接连字符”-”,并以至少1个小写字母结尾的字符串 |
\\b | 匹配目标字符串的边界 | han\\b | 字符串的边界指子串间有空格,或者是目标字符串的结束位置 |
\\B | 匹配目标字符串的非边界 | han\\B | 和 \\b 的含义刚刚相反,目标字符串的开始位置 |
分组
常用分组构造形式 | 说明 |
---|---|
(pattern) | 非命名捕获。捕获匹配的子字符串。编号为零的第一个捕获是由整个正则表达式摸式匹配的文本,其它捕获结果则根据左括号的顺序从开始自动编号。 |
(?< name> pattern) | 命名捕获。将匹配的子字符串捕获到一个组名称回或编号名称中。用于name的字符串不能包含任何标点符号,并且不能以数字开头。可以使用单引号替代尖括号,例如(?'name) |
(?:pattern) | 匹配pattern但不捕获该匹配的子表达式,即它是一个非捕获匹配,不存储供以后使用的匹配。这对于用”or“字符(|)组合模式部件的情况很有用。例如,'industr(?|yies)是比’industry|industries’更经济的表达式。 |
(?=pattern) | 它是一个非捕获匹配。例如,Windows(?=95|98|NT|2000)‘匹配"Windows2000"中"Windows",但不匹配"Windows 3.1"中的"Vindows’"。 |
(?!pattern) | 该表达式匹配不处于匹配pattern的字符串的起始点的搜索字符串。它是一个非捕获匹配。例如,Vindows(19598NT2000)‘匹配"Windows3.1"中的"Windows",但不匹配"Windows 2000"中的"Windows’"。 |
非命名捕获
public static void main(String[] args) {
String content "hanshunping s7789 nn1189han";
//下面就是非命名分组
// 1.matcher.group(0)得到匹配到的字符串
// 2.matcher.group(1)得到匹配到的字符串的第1个分组内容
// 3.matcher.group(2)得到匹配到的字符串的第2个分组内容
String regstr = "(\\d\\d)(\\d\\d)";
Pattern pattern = Pattern.compile(regstr);
Matcher matcher = pattern.matcher(content);
// 使用 while 循环遍历匹配结果
while (matcher.find()) {
// 输出匹配到的内容
System.out.println("=" + matcher.group(0));
System.out.println("第 1 个分组内容=" + matcher.group(1));
System.out.println("第 2 个分组内容=" + matcher.group(2));
}
}
命名捕获
public static void main(String[] args) {
String content "hanshunping s7789 nn1189han";
//命名分组: 即可以给分组取名
String regStr = "(?<g1>\\d\\d)(?<g2>\\d\\d)";//匹配 4 个数字的字符串
Pattern pattern = Pattern.compile(regstr);
Matcher matcher = pattern.matcher(content);
// 使用 while 循环遍历匹配结果
while (matcher.find()) {
System.out.println("找到=" + matcher.group(0));
System.out.println("第 1 个分组内容=" + matcher.group(1));
System.out.println("第 1 个分组内容[通过组名]=" + matcher.group("g1"));
System.out.println("第 2 个分组内容=" + matcher.group(2));
System.out.println("第 2 个分组内容[通过组名]=" + matcher.group("g2"));
}
}
(?:pattern)
public static void main(String[] args) {
String content = "hello 韩顺平教育 jack 韩顺平老师 韩顺平同学 hello 韩顺平学生";
// 找到 韩顺平教育 、韩顺平老师、韩顺平同学 子字符串
// String regStr = "韩顺平教育|韩顺平老师|韩顺平同学";
// 上面的写法可以等价非捕获分组, 注意:不能 matcher.group(1)
String regStr = "韩顺平(?:教育|老师|同学)";
Pattern pattern = Pattern.compile(regstr);
Matcher matcher = pattern.matcher(content);
// 使用 while 循环遍历匹配结果
while (matcher.find()) {
System.out.println("找到=" + matcher.group(0));
}
}
(?=pattern)
public static void main(String[] args) {
String content = "hello 韩顺平教育 jack 韩顺平老师 韩顺平同学 hello 韩顺平学生";
// 找到 韩顺平 这个关键字,但是要求只是查找韩顺平教育和 韩顺平老师 中包含有的韩顺平
// 下面也是非捕获分组,不能使用 matcher.group(1)
String regStr = "韩顺平(?=教育|老师)";
Pattern pattern = Pattern.compile(regstr);
Matcher matcher = pattern.matcher(content);
// 使用 while 循环遍历匹配结果
while (matcher.find()) {
System.out.println("找到=" + matcher.group(0));
}
}
(?!pattern)
public static void main(String[] args) {
String content = "hello 韩顺平教育 jack 韩顺平老师 韩顺平同学 hello 韩顺平学生";
// 找到 韩顺平 这个关键字,但是要求只是查找 不是 (韩顺平教育 和 韩顺平老师) 中包含有的韩顺平
// 下面也是非捕获分组,不能使用 matcher.group(1)
String regStr = "韩顺平(?!教育|老师)";
Pattern pattern = Pattern.compile(regstr);
Matcher matcher = pattern.matcher(content);
// 使用 while 循环遍历匹配结果
while (matcher.find()) {
System.out.println("找到=" + matcher.group(0));
}
}
正则表达式三个常用类
Pattern:正则表达式
Matcher:对输入字符串进行解释和匹配的引擎
PatternSyntaxException:表示一个正则表达式模式中的语法错误
Pattern类的方法matches --> 整体匹配,返回boolean
public class PatternMethod {
public static void main(String[] args) {
String content = "hello abc hello, 韩顺平教育";
String regExp = "hello.*";
boolean matches = Pattern.matches(regExp, content);
System.out.println("整体匹配=" + matches);
}
}
Matcher类
方法 | 说明 |
---|---|
public int start() | 返回以前匹配的初始索引。 |
public int start(int group) | 返回在以前的匹配操作期间,由给定组所捕获的子序列的初始索引 |
public int end() | 返回最后匹配字符之后的偏移量。 |
public int end(int group) | 返回在以前的匹配操作期间,由给定组所捕获子序列的最后字符之后的偏移量。 |
public boolean lookingAt() | 尝试将从区域开头开始的输入序列与该模式匹配。 |
public boolean find() | 尝试查找与该模式匹配的输入序列的下一个子序列。 |
public boolean find(int start) | 重置此匹配器,然后尝试查找匹配该模式、从指定索引开始的输入序列的下一个子序列。 |
public boolean matches() | 尝试将整个区域与模式匹配。MatcheMethod,java |
分组、捕获、反向引用
分组:可以用圆括号组成一个比较复杂的匹配摸式,那么一个圆括号的部分可以看作是一个子表达式/一个分组。
捕获:把正则表达式中子表达式/分组匹配的内容,保存到内存中以数字编号或显式命名的组里,方便后面引用,从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。组0代表的是整个正则式
反向引用:圆括号的内容被捕获后,可以在这个括号后被使用,从而写出一个比较实用的匹配摸式,这个我们称为反向引用,这种引用既可以是在正则表达式内部,也可以是在正则表达式外部,内部反向引用分组号,外部反向引用$分组号
String 类中使用正则表达式
// 替换
public String replaceAll(String regex,String replacement)
// 判断
public boolean matches(String regex)
// 分割
public String[] split(String regex)
学习参考:韩顺平讲Java