下面看看逆序环视结构:
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