环视是指正则表达式引擎先对字符串前后进行环顾观察,再进一步进行匹配操作。环视可分为顺序环视和逆序环视。
环视是不占用宽度的。其含义为:
(性质1)环视所匹配的结果不纳入最终结果,是非捕获匹配
(性质2)环视匹配时匹配指针不会移动
1 顺序环视
顺序环视又称前瞻,即向前查看字符串是否符合相应的条件,若符合才能算当前匹配成功,否则失败。表达式(?=pattern)和(?!pattern)前者表示肯定性前瞻,后者表示否定性前瞻。
1.1(?=pattern)
1.1.1 介绍
(?=pattern)是顺序环视的一种,表示肯定性前瞻,即当前字符串的周围符合pattern时,匹配才算成功。
例如:
String : abc123abc234abcdef
regex : abc(?=234)
abc(?=234)表示后边跟着123的abc才算是符合条件,即只有abc123中的abc能匹配成功,abc234和abcdef中的abc都不能匹配成功。
注意:这里是abc123中的abc可以匹配成功,而不是abc123可以匹配成功。
1.1.2 代码实现与验证
- 验证肯定性前瞻的功能及性质1
给出Java版的实现:
private static void forwardPredicting1(){
Pattern pattern = Pattern.compile("abc(?=234)");
Matcher matcher = pattern.matcher("abc123abc234abcdef");
while (matcher.find()){
System.out.println(matcher.group());
System.out.println(matcher.start() + "-----" + matcher.end());
}
}
运行结果为:
abc
6-----9
从运行结果可以看出只有字符串的索引范围为[6,9)的子串abc被匹配到了,即只有后边跟着123的abc子串符合条件。从运行结果可以看出既符合前瞻的功能也满足环视的性质1。
-
验证性质2
private static void forwardPredicting2(){ Pattern pattern = Pattern.compile("c(?=234)abc"); //只有这行改变 Matcher matcher = pattern.matcher("abc123abc234abcdef"); while (matcher.find()){ System.out.println(matcher.group()); System.out.println(matcher.start() + "-----" + matcher.end()); } }
运行结果为空。这是因为当引擎扫描到c234的c时,发现c满足前瞻的条件,继续向下扫描,但此时指针指向的是c的下一字符也就是2,发现a与2不匹配则匹配失败。
1.2 (?!pattern)
(?!pattern)是顺序环视的一种,表示否定性前瞻,即当前字符串的周围不符合pattern时,匹配才算成功。因与肯定性前瞻很相似,这里只给出具体验证代码。
private static void forwardPredicting3(){
Pattern pattern = Pattern.compile("abc(?!234)"); //只有这行改变
Matcher matcher = pattern.matcher("abc123abc234abcdef");
while (matcher.find()){
System.out.println(matcher.group());
System.out.println(matcher.start() + "-----" + matcher.end());
}
}
运行结果为:
abc
0-----3
abc
12-----15
可以看出,除了abc234的abc,其余的abc都被匹配到了。
2 逆序环视
逆序环视又称后顾,即向后查看已扫描过的字符串是否符合相应的条件,若符合才能算当前匹配成功,否则失败。表达式(?<=pattern)和(?<!pattern)前者表示肯定性后顾,后者表示否定性后顾。
2.1 (?<=pattern)
给出验证代码:
private static void backwardPredicting1(){
Pattern pattern = Pattern.compile("(?<=123)abc");
Matcher matcher = pattern.matcher("abc123abc234abcdef");
while (matcher.find()){
System.out.println(matcher.group());
System.out.println(matcher.start() + "-----" + matcher.end());
}
}
代码表示只匹配123abc中的abc,所以运行结果为:
abc
6-----9
2.2 (?<!pattern)
给出验证代码:
private static void backwardPredicting2(){
Pattern pattern = Pattern.compile("(?<!123)abc");
Matcher matcher = pattern.matcher("abc123abc234abcdef");
while (matcher.find()){
System.out.println(matcher.group());
System.out.println(matcher.start() + "-----" + matcher.end());
}
}
代码表示只要abc前边不是123的都可以匹配,所以运行结果为:
abc
0-----3
abc
12-----15