初见这个工具包的时候,就有一种疑惑,用String作为输入好好的,为什么要另外搞一个PatternMatcherInput呢?
现在,我大概说一下自己的看法吧。PatternMatcherInput与普通String的最大区别是:PatternMatcherInput是有状态的。所谓的有状态:就保存了当前匹配到的位置,这个值保存到_currentOffset字段上。
可以这么理解:
PatternMatcherInput=String(char[])+状态(currentOffset)
但是,至于PatternMatcherInput的状态是否update了,就要看操作的方法。
contain()是有update到的。
好吧,一切用实例说话。
如果我们使用String作为输入:
java源码:
public class test {
public static void main(String[] args) {
PatternMatcher matcher;
PatternCompiler compiler;
Pattern pattern;
PatternMatcherInput input;
MatchResult result;
compiler = new Perl5Compiler();
matcher = new Perl5Matcher();
String somePatternString="\\b\\d+\\b";
String someStringInput="3231 432432 432424";
try {
pattern = compiler.compile(somePatternString);
} catch(MalformedPatternException e) {
System.out.println("Bad pattern.");
System.out.println(e.getMessage());
return;
}
int i=1;
while(matcher.contains(someStringInput, patter)) {
result = matcher.getMatch();
System.out.println("contain "+i+": "+result.toString());
i++;
}
}
}
console结果:
contain 1: 3231
contain 2: 3231
contain 3: 3231
contain 4: 3231
contain 5: 3231
contain 6: 3231
contain 7: 3231
contain 8: 3231
contain 9: 3231
contain 10: 3231
contain 11: 3231
contain 12: 3231
contain 13: 3231
contain 14: 3231
contain 15: 3231
contain 16: 3231
contain 17: 3231
contain 18: 3231
contain 19: 3231
contain 20: 3231
contain 21: 3231
contain 22: 3231
contain 23: 3231
contain 24: 3231
contain 25: 3231
contain 26: 3231
contain 27: 3231
contain 28: 3231
contain 29: 3231
contain 30: 3231
contain 31: 3231
contain 32: 3231
contain 33: 3231
contain 34: 3231
contain 35: 3231
contain 36: 3231
contain 37: 3231
contain 38: 3231
contain 39: 3231
contain 40: 3231
contain 41: 3231
contain 42: 3231
contain 43: 3231
contain 44: 3231
contain 45: 3231
contain 46: 3231
contain 47: 3231
contain 48: 3231
contain 49: 3231
contain 50: 3231
contain 51: 3231
contain 52: 3231
contain 53: 3231
contain 54: 3231
contain 55: 3231
contain 56: 3231
contain 57: 3231
contain 58: 3231
contain 59: 3231
contain 60: 3231
contain 61: 3231
contain 62: 3231
contain 63: 3231
contain 64: 3231
contain 65: 3231
contain 66: 3231
contain 67: 3231
contain 68: 3231
contain 69: 3231
contain 70: 3231
contain 71: 3231
contain 72: 3231
contain 73: 3231
contain 74: 3231
(……………………………………会不断下去!!!!!!1)
分析:
出现这样子的原因是:
因为while(matcher.contains(someStringInput, patter)) {这一句:
里面传递的是someStringInput(一个普通的String对象)没有状态,每个loop传入contain()方法的都是原来的someStringInput而contain()只会检索字符串中的第一个匹配字段,所以会不断持续下去!
而如果改用PatternMatcherInput:
java源代码:
public class test {
public static void main(String[] args) {
PatternMatcher matcher;
PatternCompiler compiler;
Pattern pattern;
PatternMatcherInput input;
MatchResult result;
compiler = new Perl5Compiler();
matcher = new Perl5Matcher();
String somePatternString="\\b\\d+\\b";
String someStringInput="3231 432432 432424";
try {
pattern = compiler.compile(somePatternString);
} catch(MalformedPatternException e) {
System.out.println("Bad pattern.");
System.out.println(e.getMessage());
return;
}
input = new PatternMatcherInput(someStringInput);
int i=1;
while(matcher.contains(input, pattern)) {
result = matcher.getMatch();
System.out.println("contain "+i+": "+result.toString());
i++;
// Perform whatever processing on the result you want.
}
}
}
console结果:
contain 1: 3231
contain 2: 432432
contain 3: 432424
分析:因为每次传入contain()方法的虽然都是同一个PatternMatcherInput实例,但是这个实例是有状态的。每个loop的开始检索位置(CurrentOffset)都位于上次成功匹配位置之后,即所谓的:update。
除此之外,还需要注意下面一个细节。
我们可以重新从头到尾检索PatternMatcherInput里面的内容。使用下面的方法,将位置设为开始处:
(input是PatternMatcherInput的一个实例)
input.setCurrentOffset(input.getBeginOffset());
我们也使用同一个PatternMatcherInput对象来指向新的输入字符。
例如:input.setInput(aNewInputString);