1.0 正则表达式的使用:
String str="csdw";
Pattern p=Pattern.compile("\\W");
Matcher m=p.matcher(str);
while(m.find()){
System.out.println(m.group());
}
形如上面的代码就是一个简单的正则,他需要从str中找到\w即找到非字符的数(详细见
正则表达式的构造摘要),这里的运行结果将是没有任何输出;
2.0 部分源代码分析
2.1.0 Patter.compile(String regex)
在使用compile中创建Pattern(regex,0)的对象,然后将传入的String对象中的字符转换成ASIC码,并存入数组中、在这里他会先将是数组长度设置为regex长度+2,然后检查是否存在\Q(引用开始的位置)和\E(引用结束的位置),然后再去掉多出来的2个占位符。源代码为
a,将数组长度加2,patternLength即为输入的regex的长度
temp = new int[patternLength + 2];
hasSupplementary = false;
int c, count = 0;
//将输入的字符转换成ASIC码
for (int x = 0; x < patternLength; x += Character.charCount(c)) {
c = normalizedPattern.codePointAt(x);
if (isSupplementary(c)) {
hasSupplementary = true;
}
temp[count++] = c;
}
b.检查和去掉含有的\Q和\E
//这是不含QE的情况,如果有兴趣可以查阅JDK源码,在java.util.regex的1571行(jdk 1.7)
final int pLen = patternLength;
int i = 0;
while (i < pLen-1) {
if (temp[i] != '\\')
i += 1;
else if (temp[i + 1] != 'Q')
i += 2;
else
break;
}
if (i >= pLen - 1) // No \Q sequence found
return;
还有许多的类似检查,api说的很清楚,源代码一般采用先初始化值,然后和十六进制的数进行比较,这个比较是用一个叫has的方法。
//一般情况下这里的f为预先定义好的十六进制数,我没有自己与过(api说明的很清楚了。与的结果很明显),
//flag是Patter.compile(string regex,int flag)传入的,具体的值请移步api(本文是1.7版本)
private boolean has(int f) {
return (flags & f) != 0;
}
以上都是前期的准备工作,将pattern初始化,啰嗦一句,这里面其实还有个分组的情况,也就是用()将你解析的值分成不同的部分,以后在学习这个问题的解决。当你输入不同的值来解析的时候将会用不同的方式将传入的正则式进行存储。
例如,如果传入的为单个字符,则会调用
static final class SingleS extends CharProperty {
final int c;
SingleS(int c) { this.c = c; }
boolean isSatisfiedBy(int ch) {
return ch == c;
}
}
但是总的来说,他们都是通过ASIC码来测试的,如果使用[a-z]这种形式,会创建一个包含所有字符,bits[boolean],然后将a-z的asic值设置为true。
private static final class BitClass extends BmpCharProperty {
final boolean[] bits;
BitClass() { bits = new boolean[256]; }
private BitClass(boolean[] bits) { this.bits = bits; }
BitClass add(int c, int flags) {
assert c >= 0 && c <= 255;
if ((flags & CASE_INSENSITIVE) != 0) {
if (ASCII.isAscii(c)) {
bits[ASCII.toUpper(c)] = true;
bits[ASCII.toLower(c)] = true;
} else if ((flags & UNICODE_CASE) != 0) {
bits[Character.toLowerCase(c)] = true;
bits[Character.toUpperCase(c)] = true;
}
}
bits[c] = true;
return this;
}
在解析的时候,通过讲传入待解析的字符串(会将传入的值转换成asic码的数组)通过asic码的值来查询上诉的bits[boolean]来查询是否为True。
boolean isSatisfiedBy(int ch) {
return ch < 256 && bits[ch];
}
如果返回为true则说明是在正则中的。
//match的核心代码
boolean match(Matcher matcher, int i, CharSequence seq) {
if (i < matcher.to) {
return isSatisfiedBy(seq.charAt(i))
&& next.match(matcher, i+1, seq);
} else {
matcher.hitEnd = true;
return false;
}
}