JAVA的正则真的比JS和PYTHON要复杂很多,或者说叫做精细吧。有两个Matcher的API不常用,但是我在《两周自制脚本语言》上面看见了。
先说说useAnchoringBounds吧,它的默认值就是false。是在Matcher 的region 不等于被匹配字符串的长度才有用的。
先看看下面的代码
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Lexer {
public static void main(String[] args){
String regex="^car";
String text = "Madagascar";
Matcher m = Pattern.compile(regex).matcher(text);
m.useAnchoringBounds(false);
m.region(7,text.length());
m.find();
System.out.println("Matches starting at character "+m.start());
}
}
/**
* 输出结果
* Exception in thread "main" java.lang.IllegalStateException: No match available
* at java.util.regex.Matcher.start(Matcher.java:343)
* at entry.Lexer.main(Lexer.java:18)
* */
直接就是一个报错。因为我们的字符串不是以car为开头的。
但是,接下来
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Lexer {
public static void main(String[] args){
String regex="^car";
String text = "Madagascar acfun acfun";
Matcher m = Pattern.compile(regex).matcher(text);
m.useAnchoringBounds(true);
m.region(7,text.length());
m.find();
System.out.println("Matches starting at character "+m.start());
/**
* 输出结果
* Matches starting at character 7
* */
}
}
就可以了,为什么呢。因为我们的region是从第七个字符开始的也就是car acfun acfun useAnchoringBounds(true); 那么匹配的就变成了 region的开头了,而不是整一个字符串的开头。
然后是第二个。useTransparentBounds(),它的默认值是false。它的作用如下。
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Lexer {
public static void main(String[] args){
String regex="\\bcar\\b";
String text = "Madagascar acfun acfun";
Matcher m = Pattern.compile(regex).matcher(text);
m.useTransparentBounds(false);
m.region(7,text.length());
m.find();
System.out.println("Matches starting at character "+m.start());
//输出结果
//Matches starting at character 7
}
}
和上次一样region依然是car acfun acfun,但是\b却好像被忽视了一样,对了,这就是它的作用,允许忽视一个类似\b的东西。
如果 useTransparentBounds 被设为true 那么结果是相反的,它会报错。