正则表达式(regex)是一个强大的字符串处理工具,其预定义的各类元字符结合而形成一套匹配字符串的模板,可以对字符串进行查找、提取、分割、替换等操作,事实上,任意字符串"xxx"都可以当成一个特殊的正则表达式使用 。
本篇主要记录一下元字符的功能表,方便后续自查,与正则表达式相关的说明在如下这篇👇
pass 先占个坑.......
Java中的String、StringBuffer等类的一些方法支持与正则表达式配合使用,最常见的为如下4种:
boolean matches(String regex):判断该字符串是否匹配指定的正则表达式。
String replaceAll(String regex, String replacement) :将该字符串中所有匹配regex的子串替换成replacement。
String replaceFirst(String regex, String replacement):将该字符串中第一个匹配regex的子串替换成replacement。
String[] split(String regex):以regex作为分隔符,把该字符串分割成多个子串。
目录
1、基本定义字符表
元字符 | 解释 |
x | 代表任意合法字符x |
\\0mnn | ASCII码八进制数0mnn所表示的字符,如"A"—>"\\0101" |
\\xhh | ASCII码十六进制数0xhh所表示的字符,如"B"—>"\\x42" |
\\uhhhh | Unicode码十六进制数0xhhhh所表示的字符,如"a"—>"\\u0061" |
\\t | 制表符,"\t"—>"\\t" |
\\n | 换行符,"\n"—>"\\n" |
\\r | 回车符,"\r"—>"\\r" |
\\f | 换页符,"\f"—>"\\f" |
\\cx | x(∈A~Z或者a~z)对应的控制符,也就是Ctrl键+x后对应字符 |
注*:不同于其他语言,Java在使用斜杠字符 "\" 来进行预处理时,都是成对即 "\\" 出现。
2、特殊定义字符表
元字符 | 解释 |
$ | 匹配一行的结尾。如"bcdd"—>"bc(dd)$",表示以dd结尾的字符串 |
^ | 匹配一行的开头。如"happy"—>"^(ha)ppy",表示以ha开头的字符串 |
* | 指定前面表达式可以出现0次或多次,如"b"或"aaaab"均满足于"a*b"表达式 |
+ | 指定前面表达式可以出现1次或多次,如"ab"或"aaaab"均满足于"a+b"表达式 |
? | 指定前面表达式可以出现0次或1次,如"b"或"ab"均满足于"a?b"表达式 |
. | 匹配除了换行符以外的任何的字符,一个"."对应一个合法字符,如"abc"—>"..." |
\ | 如上表所见,用来转义字符,或指定八、十六进制 |
| | 指定 | 前后的两个表达式中一项即可,如"A|BC"—>"A"或者"BC"均满足 |
括号 | "[ ]" "{ }" "( )"三种括号 |
注*: 若要匹配上述元字符的原型,需要加上"\\",即匹配字符"$"、"?"的表达式为"\\$"、"\\?"。特别地,匹配"\"的表达式为"\\\\"(4个\),这是由于Java字符串中反斜杠本身需要转义,因此两个反斜杠(\\)实际上相当于一个(前一个用于转义)。
3、三种括号表达式
正则表达式语法中赋予了"[ ]"、"( )"、"{ }"这三类括号特殊的含义,使之控制字符的范围、分组、频度。
( ):捕获组
在已经规定好的正则表达式中可以通过添加一系列( )来进行分组后相应地匹配。
例如对于A、B、C三种表达式的组合字符串表达式"ABC"可进行分组为:"((A)(B(C)))"。(其中A、B、C的含义可以举例理解为A在匹配数字、B在匹配字母、C在匹配其他符号)
而确定表达式中有几个组通过从左到右计算开括号来编号的,
对于上式,会分为4个组,
组1:((A)(B(C))) 整个表达式
组2:(A) 组3:(B(C)) 组4:(C)
而要提取各组匹配的结果,可通过matcher对象的group()方法,向其传入一个int型参数,即可得到对应组别的结果。规定group(0)为整个匹配到的表达式结果,group(1)为第一组的结果... ...
现分析如下代码:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
var s = "How much is the bottle, 999? NoNoNo!";
var regex = "((\\D*)(\\d+)(.*))";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(s);
System.out.println("匹配到了" + matcher.groupCount() + "个组");
if (matcher.find()){
System.out.println(matcher.group(0));
System.out.println(matcher.group(1));
System.out.println(matcher.group(2));
System.out.println(matcher.group(3));
System.out.println(matcher.group(4));
}
}
}
定义了分组化的正则表达式为"((\\D*)(\\d+)(.*))",新建matcher对象后与字符串s进行匹配,按照上述分析"( )"应将s分成4个组,可通过调用matcher的groupCount()方法得到组数来验证。
然后各个组的匹配结果通过group()方法获取
- 第0组:((\\D*)(\\d+)(.*))—(规定)整个字符串—"How much is the bottle, 999? NoNoNo!"
- 第1组:((\\D*)(\\d+)(.*))—(自设)整个字符串—"How much is the bottle, 999? NoNoNo!"
- 第2组:(\\D*)—0次或多次非数字字符(这里是多次)—"How much is the bottle, "
- 第3组:(\\d+)—从第2组的尾部开始,1次或多次数字字符(这里是多次)—"999"
- 第4组:(.*)—从第3组的尾部开始,0次或多次任意合法字符(这里是多次)—"? NoNoNo!"
至于为何"*" "+"字符会在0、1次或多次中选择多次匹配,这跟Java正则表达式匹配的默认模式——贪婪模式(Greedy)有关,最后运行结果验证。
除此之外,( )还可用于限定正则表达式中元字符具体作用于哪部分的内容,如对于表达式"go?d"和"(go)?d","?" 分别作用于"o"和"go"。
[ ]:范围与组合表达式
利用方括号"[ ]"可以使得一些表达式类似于集合那样进行运算。
- 无其他符号表示枚举:[ ]中的所有字符的含义表示为“其中一个”,例如对于[abc]表示"a" "b" "c"中的任意一个即可匹配。
- 加上"-"表示范围:在任意两个合法字符间 x 与 y 加上"-"表示 x 到 y 范围内的字符,其依据是根据连续的Unicode码,例如对于"[a-z]"表示a到z之间的字符(含a或z),即任意一个小写字母;再比如结合枚举,[a-zA-Z]表示不区分大小写的任意英文字母。
- 加上"^"表示求否:对于方括号里面的表达式,加上"^"表示“除了表达式以外范围的字符”,例如[^abc],表示非a、b、c的任意字符,[^a-z]表示不在小写英文字母范围内的任意其他字符。
- 加上"&&"表示"与"运算:这里的 "&&" 的概念很像数学集合上的 "∩",任意两表达式间加上 "&&" 表示“在它们交运算后的字符范围",例如[a-e&&c-g]表示c、d、e三个字符中的一个。由此,对于相同的正则表达式含义,可能有几种不同的表现形式,例如:
a-z内除去b和c的任意字符 [ad-z] 或者是 [a-z&&[^bc]] a-z除去m~p范围的任意字符 [a-z&&[^m-p]] 或者是[a-lq-z] - 嵌套[ ]表示"并"运算:类似于数学集合的"∪",在[ ]内使用多个方括号表达式时,组合起来就是各个范围的并集,表示”要么在这个范围要么在那个范围内的任意字符“,例如"[[0-9][a-z]]"表示数字或者是小写字母。
{ }:字符频度限定
{n} | 表示字符出现且仅出现n次,例如"a{2}"—>false,"aa{2}"—>true |
{n,} | 表示字符至少出现n次,例如"a{2}"—>false,"aaaa{2}"—>true |
{n,m} | 表示字符出现的次数为n~m,例如"aa{3,5}"—>false,"aaaa{3,5}"—>true |
"{ }"还可以结合"[ ]"一起使用得到匹配范围更确切的正则表达式。
4、边界匹配符表
除了上述已经提过的"^"开头和"$"结尾,还有一些其他情况下的边界匹配符
元字符 | 解释 |
\\b | 单词边界 |
\\B | 非单词边界 |
\\A | 输入的开头 |
\\G | 上一个匹配的结尾 |
\\Z | 输入的结尾,仅用于最后的结束符(如果有的话) |
\\z | 输入的结尾 |
虽然"^"、"$"与表格中部分匹配符均有匹配开头或是结尾的意思,但其区别在于"^"、"$"作用体现在一行字符串上面,而"\\b"等体现在当一行字符串里有多个以空格隔开的单词时,每个独立的单词上面。
5、通配符表
元字符作为通配符的含义是指利用一个元字符代替了一段字符区间,大大简化了正则表达式的表现形式。
元字符 | 解释 |
\\d | 数字0~9,也可理解为[0-9] |
\\D | 非数字0~9,也可理解为[^0-9] |
\\s | 所有表现空白的字符,如空格、制表符、回车、换行(页)符等 |
\\S | 所有表现非空白的字符 |
\\w | 匹配所有的单词字符,也就是0~9数字、26个字母和下划线 "_"(变量名的组成元素) |
\\W | 匹配所有的非单词字符,也就是除去上一行所提的字符范围 |
助记:
d——digit(数字)
s——space(空白)
w——word(单词)
大写就是求否。