下面看看逆序环视结构:
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
肯定逆序环视结构,用来查找前面为see
(?<!s)ee
否定逆序环视结构,用来查找之前不为see
环视的注意事项:
环式结构仅用于布尔判断,结构内的子表达式所匹配的文本,不会保存在整个表达式的匹配结果中
逆序环视结构对子表达式存在限制
逆序环视结构的限制
PerlPython:逆序环视结构中的子表达式必须为固定长度
就是不能使用任何量词,也不能使用多选分支,长度不相同的多选结构
PHPJava:逆序环视结构中的子表达式可以不定长度,但必须由上限
就是不能使用 *这样的量词。
.NET:逆序环视结构中的子表达式完全没有限制
从这个意义上说,.NET的正则表达式是做的最好的。
环视应用实例:
修整数值
要求:在数值中的合适位置插入逗号,将其修整为便于阅读的形式
举例:
·1234567890->1,234,567,890
·123456->123,456
环视应用实例:
需要插入逗号的位置:
·左侧至少出现一位数字,右侧出现的数字位数是3的倍数
正则表达式:
· (?=\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应该显示为,123456
1234567890 应该为:1234567890
问题出在:
  "(?<=\\d) (?=(\\d{3} ) +) " ;
右边出现的是3的倍数,对这个字符串长度,就是匹配到哪个为止,我们并没有限定。
对肯定顺序环结构对字符串的匹配加以更准确的限制。
应该再添加一个否定循环结构:
String regex =  "(?<=\\d)(?=(\\d{3})+(?!\\d))" ;
替换前:123456
替换后:123,456
替换前:1234567890
替换后:1,234,567,890
小结:
锚点:规定匹配的位置
· \b^$\A\Z
环视:以子表达式对位置进行判断
·(?=)(?!)
·(?<)(?<!)
·环视只能进行布尔判断
·逆序环视的限制
正则表达式 学习笔记4 完!