天天看点

正则表达式 学习笔记4.3

下面看看逆序环视结构:

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 {

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))";

替换后:123,456

替换后:1,234,567,890

小结:

l 锚点:规定匹配的位置

· \b、^、$、\A、\Z

l 环视:以子表达式对位置进行判断

·(?=)、(?!)

·(?<)、(?<!)

·环视只能进行布尔判断

·逆序环视的限制

正则表达式 学习笔记4 完!

本文转自jooben 51CTO博客,原文链接:http://blog.51cto.com/jooben/318587