下面看看逆序环视结构:
public class GeneralSix {
public static void main(String[] args) {
String[] strings = new String[]{"see","bee","tee"};
String[] regexs = new String[]{"(?<=s)ee","(?<!s)ee"};
for(String regex:regexs){
for(String str:strings){
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(str);
if(m.find()){
System.out.println("\"" + str +"\" 能够匹配正则:"+regex);
}else{
System.out.println("\"" + str +"\" 不能够匹配正则:"+regex);
}
}
System.out.println("");
}
}
}
运行结果:
"see" 能够匹配正则:(?<=s)ee
"bee" 不能够匹配正则:(?<=s)ee
"tee" 不能够匹配正则:(?<=s)ee
"see" 不能够匹配正则:(?<!s)ee
"bee" 能够匹配正则:(?<!s)ee
"tee" 能够匹配正则:(?<!s)ee
(?<=s)ee
肯定逆序环视结构,用来查找前面为s的ee。
(?<!s)ee
否定逆序环视结构,用来查找之前不为s的ee
环视的注意事项:
l 环式结构仅用于布尔判断,结构内的子表达式所匹配的文本,不会保存在整个表达式的匹配结果中
l 逆序环视结构对子表达式存在限制
逆序环视结构的限制
l Perl,Python:逆序环视结构中的子表达式必须为固定长度
就是不能使用任何量词,也不能使用多选分支,长度不相同的多选结构
l PHP,Java:逆序环视结构中的子表达式可以不定长度,但必须由上限
就是不能使用 *、+ 这样的量词。
l .NET:逆序环视结构中的子表达式完全没有限制
从这个意义上说,.NET的正则表达式是做的最好的。
环视应用实例:
l 修整数值
l 要求:在数值中的合适位置插入逗号,将其修整为便于阅读的形式
l 举例:
·1234567890->1,234,567,890
·123456->123,456
环视应用实例:
l 需要插入逗号的位置:
·左侧至少出现一位数字,右侧出现的数字位数是3的倍数
l 正则表达式:
·(?=\d)(?=(\d{3}+))
public class GeneralSeven {
public static void main(String[] args) {
String[] numbers = new String[]{"123456","1234567890"};
String regex = "(?<=\\d)(?=(\\d{3})+)";
for(String number:numbers){
System.out.println("替换前:"+number);
System.out.println("替换后:"+number.replaceAll(regex, ","));
}
}
}
运行结果:
替换前:123456
替换后:1,2,3,456
替换前:1234567890
替换后:1,2,3,4,5,6,7,890
这个结果有问题,123456应该显示为,123,456
1234567890 应该为:1,234,567,890
问题出在:
"(?<=\\d)(?=(\\d{3})+)";
右边出现的是3的倍数,对这个字符串长度,就是匹配到哪个为止,我们并没有限定。
对肯定顺序环结构对字符串的匹配加以更准确的限制。
应该再添加一个否定循环结构:
String regex = "(?<=\\d)(?=(\\d{3})+(?!\\d))";
替换前:123456
替换后:123,456
替换前:1234567890
替换后:1,234,567,890
小结:
l 锚点:规定匹配的位置
· \b、^、$、\A、\Z
l 环视:以子表达式对位置进行判断
·(?=)、(?!)
·(?<)、(?<!)
·环视只能进行布尔判断
·逆序环视的限制
正则表达式 学习笔记4 完! 本文转自jooben 51CTO博客,原文链接:http://blog.51cto.com/jooben/318587