- 常见的元字符.*+()$/?[]^{}
- 限定符:? * + {}
其中? 表示出现0次或1次
*表示出现0次或n次
+表示出现1次或n次
{}表示出现指定次数,{2}表示2次 {2,3}出现两次或3次{3,}表示出现3次以上 - 或运算:|
比如 a(ac|bc) 可以匹配字符aac和abc - 字符类:[] []+ [^]
比如[a,b,c,d] 可以匹配a,b,c,d
[0-9a-zA-Z]+表示可以匹配所有的字母和数字
[^abc]表示可以匹配除了a,b,c之外的任意1个字符,包括数字和特殊符号 - 元字符
d表示[0-9]匹配所有数字
w表示英文数字下划线
s表示空白符
D表示非数字字符
W表示非单词字符
S表示非空白字符,但不包括换行符
**.**表示任意字符,但不包括换行符
**^**匹配行首
**$**匹配行尾
- 需求: 匹配IPv4的地址
String content = "192.234.65.12端口和12.4.5.6还有189.256.23.9等等";
- 设计正则表达式
((25[0-5]|2[0-4]d|1d{2}|[1-9]?d).){3}(25[0-5]|2[0-4]d|1d{2}|[1-9]?d)
String regStr = "((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)";
- 创建模式对象即正则表达式对象(Pattern)
Pattern pattern = Pattern.compile(regStr);
- 创建匹配器(创建匹配器matcher,按照正则表达式的规则)
Matcher matcher = pattern.matcher(content);
- 开始匹配
while(matcher.find()){
System.out.println(matcher.group());
}
原码分析
Matcher matcher = pattern.matcher(content);
首先就是创建匹配器对象,调用了Matcher的构造方法
Matcher中的CharSequence属性此属性为String的一个父接口
通过构造器将CharSequence赋初值(子类的引用指向父类的对象)
matcher.group(0);
这个地方的text.getSubSequence()其实运用了多态,运行的是String类中的此方法
- 在开始匹配的过程中有以下几个步骤(matcher.find()分析)
-
根据指定的规则,定位满足规则的子字符串
-
找到后,将子字符串的开始的索引记录到matcher对象的属性int[] groups;
第一次找到就将groups[0]记录下来,在结束的位置就记录下groups[1] -
同时记录属性oldLastd 值为 子字符串的结束的索引+1的值,下一次执行find时就从此位置开始
- matcher.group()分析
- 根据groups[0] 和 groups[1]的记录的位置,从content开始截取子字符串返回,当然是不包含groups[1]的位置



