簡書著作權(quán)歸作者所有,任何形式的轉(zhuǎn)載都請聯(lián)系作者獲得授權(quán)并注明出處。
? ? ? ?正則表達式為匹配特定模式的字符串提供了便利。正則表達式中也有很多值得注意的細節(jié)問題,本篇文章主要通過一些實例講述一下正則中斷言的使用方法,以便在開發(fā)過程中進行查閱。
? ? ? ?正則中的斷言有如下幾種形式:
? ? ? ?(?=pattern)
? ? ? ?(?!pattern)
? ? ? ?(?<=pattern)
? ? ? ?(?<!pattern)
? ? ? ?接下來通過實例一一演示其作用及使用方式:
? ? ? ?1、(?=pattern)
// 演示代碼
public class PatternAssertion {
public static void main(String[] args) {
String input = "Hello Bubble Bulk";
Matcher matcher = Pattern.compile("Bu(?=bb)").matcher(input);
while (matcher.find()) {
int begin = matcher.start();
int end = matcher.end();
System.out.println("matched string: " + input.substring(begin, end));
System.out.println("span: (" + begin + ", " + end + ")");
}
}
}
? ? ? ?執(zhí)行結(jié)果
matched string: Bu
span: (6, 8)
? ? ? ?通過執(zhí)行結(jié)果可以看出,"Bu(?=bb)" 這個正則只匹配到了 "Bubble" 中的 "Bu",并沒有匹配到 "Bulk" 中的 "Bu" 。這是因為 "Bu(?=bb)" 中的 "(?=bb)" 限制了 "Bu" 后面的模式必須是 "bb" ,因此在整個字符串 "Hello Bubble Bulk" 中,只有 "Bubble" 里面的這個 "Bu" 才是滿足條件的。
? ? ? ?2、(?!pattern)
// 演示代碼
public class PatternAssertion {
public static void main(String[] args) {
String input = "Hello Bubble Bulk";
Matcher matcher = Pattern.compile("Bu(?!bb)").matcher(input);
while (matcher.find()) {
int begin = matcher.start();
int end = matcher.end();
System.out.println("matched string: " + input.substring(begin, end));
System.out.println("span: (" + begin + ", " + end + ")");
}
}
}
? ? ? ?執(zhí)行結(jié)果
matched string: Bu
span: (13, 15)
? ? ? ?通過執(zhí)行結(jié)果可以看出,"Bu(?!bb)" 這個正則只匹配到了 "Bulk" 中的 "Bu",并沒有匹配到 "Bubble" 中的 "Bu" 。這是因為 "Bu(?!bb)" 中的 "(?!bb)" 限制了 "Bu" 后面的模式不能是 "bb" ,因此在整個字符串 "Hello Bubble Bulk" 中,只有 "Bulk" 里面的這個 "Bu" 才是滿足條件的。
? ? ? ?3、(?<=pattern)
// 演示代碼
public class PatternAssertion {
public static void main(String[] args) {
String input = "Hello Bubble Bulk";
Matcher matcher = Pattern.compile("(?<=o\\s)Bu").matcher(input);
while (matcher.find()) {
int begin = matcher.start();
int end = matcher.end();
System.out.println("matched string: " + input.substring(begin, end));
System.out.println("span: (" + begin + ", " + end + ")");
}
}
}
? ? ? ?執(zhí)行結(jié)果
matched string: Bu
span: (6, 8)
? ? ? ?通過執(zhí)行結(jié)果可以看出,"(?<=o\s)Bu" 這個正則只匹配到了 "Bubble" 中的 "Bu",并沒有匹配到 "Bulk" 中的 "Bu" 。這是因為 "(?<=o\s)Bu" 中的 "(?<=o\s)" 限制了 "Bu" 前面的模式必須是 "o\s" ,因此在整個字符串 "Hello Bubble Bulk" 中,只有 "Bubble" 里面的這個 "Bu" 才是滿足條件的。
? ? ? ?4、(?<!pattern)
// 演示代碼
public class PatternAssertion {
public static void main(String[] args) {
String input = "Hello Bubble Bulk";
Matcher matcher = Pattern.compile("(?<!o\\s)Bu").matcher(input);
while (matcher.find()) {
int begin = matcher.start();
int end = matcher.end();
System.out.println("matched string: " + input.substring(begin, end));
System.out.println("span: (" + begin + ", " + end + ")");
}
}
}
? ? ? ?執(zhí)行結(jié)果
matched string: Bu
span: (13, 15)
? ? ? ?通過執(zhí)行結(jié)果可以看出,"(?<!o\s)Bu" 這個正則只匹配到了 "Bulk" 中的 "Bu",并沒有匹配到 "Bubble" 中的 "Bu" 。這是因為 "(?<!o\s)Bu" 中的 "(?<!o\s)" 限制了 "Bu" 前面的模式不能是 "o\s" ,因此在整個字符串 "Hello Bubble Bulk" 中,只有 "Bulk" 里面的這個 "Bu" 才是滿足條件的。
不消耗字符
? ? ? ?正則中的斷言在參與匹配時是不消耗字符串中的字符的,斷言只是起到一個限制的作用。下面舉例說明:
public class PatternAssertion {
public static void main(String[] args) {
String input = "Hello Bubble Bulk";
Matcher matcher = Pattern.compile("Bu(?=l).").matcher(input);
while (matcher.find()) {
int begin = matcher.start();
int end = matcher.end();
System.out.println("matched string: " + input.substring(begin, end));
System.out.println("span: (" + begin + ", " + end + ")");
}
}
}
? ? ? ?執(zhí)行結(jié)果
matched string: Bul
span: (13, 16)
? ? ? ?這里使用的帶斷言的正則是 "Bu(?=l)." ,為了便于理解,在分析這個正則的時候可以先把其中的斷言部分去掉,這樣正則就變成了 "Bu." 。這個正則對整個字符串 "Hello Bubble Bulk" 進行匹配時會匹配到 "Bub" 和 "Bul" 兩處,然而正則 "Bu(?=l)." 中的斷言要求 "Bu" 后面只能是 "l" ,因此最終只有 "Bul" 滿足條件,而 "Bub" 是不滿足條件的。