零宽断言java_正则表达之零宽断言(零宽度正预测先行断言)
最近為了對html文件進行源碼處理,需要進行正則查找并替換。于是借著這個機會把正則系統地學一下,雖然以前也用過正則,但每次都是臨時學一下混過關的。在學習的過程中還是遇到不少問題的,特別是零寬斷言(這里還要吐槽下,網上到處都是都復制粘貼的內容,遇到個問題查看了不少重復的東西,汗!!!),所以在這里把自己的理解寫下來,方便以后查閱!
零寬度正預測先行斷言是什么呢,看msdn上的官方解釋定義
(?=?子表達式)
(零寬度正預測先行斷言。)僅當子表達式在此位置的右側匹配時才繼續匹配。例如,\w+(?=\d)?與后跟數字的單詞匹配,而不與該數字匹配。
經典的例子:某單詞以ing結尾,要獲取ing前面的內容
var reg = new Regex(@"\w+(?=ing)");
var str = "muing";
Console.WriteLine(reg.Match(str).Value);//返回mu
以上是網上到處可見的例子,到這里或許你明白了,原來就是返回了exp表達式前面的內容。
再看下面的的代碼
var reg = new Regex(@"a(?=b)c");
var str = "abc";
Console.WriteLine(reg.IsMatch(str));//返回false
為什么會返回false?
其實msdn官方定義已經說了,只是它說得很官方而已。這里需要我們注意一個關鍵點:此位置。沒錯,是位置而不是字符。那么結合官方定義和第一個例子來理解第二個例子:
因為a后面是b,則此時返回了匹配內容a(由第一個例子知道,只返回a不返回exp匹配的內容),此時a(?=b)c中的a(?=b)部分已經解決了,接下來要解決c的匹配問題了,此時匹配c要從字符串abc哪里開始呢,結合官方定義,就知道是從子表達的位置向右開始的,那么就是從b的位置開始,但b又不匹配a(?=b)c剩余部分的c,所以abc就不匹配a(?=b)c了。
那么如果要上面的進行匹配,正則應該如何寫呢?
答案是:a(?=b)bc
當然,有人會說直接abc就匹配上了,還要這么折騰嗎?當然不用這么折騰,只是為了說明零寬度正預測先行斷言到底是怎么一回事?關于其它的零寬斷言也是同一原理!
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
(?= 子表達式)
(零寬度正預測先行斷言。) 僅當子表達式在此位置的右側匹配時才繼續匹配。例如,\w+(?=\d) 與后跟數字的單詞匹配,而不與該數字匹配。此構造不會回溯。
(?<= 子表達式)
(零寬度正回顧后發斷言。) 僅當子表達式在此位置的左側匹配時才繼續匹配。例如,(?<=19)99 與跟在 19 后面的 99 的實例匹配。此構造不會回溯。
http://deerchao.net/tutorials/regex/regex.htm
(?<= # 斷言要匹配的文本的前綴
# 查找尖括號括起來的字母或數字(即HTML/XML標簽)
) # 前綴結束
.* # 匹配任意文本
(?= # 斷言要匹配的文本的后綴
# 查找尖括號括起來的內容:前面是一個"/",后面是先前捕獲的標簽
) # 后綴結束
下面講下我的理解:
(1).零寬度
這表示匹配是一個位置(Loaction)而不是子表達式。
(2).預測先行,回顧后發
(?= 子表達式),預測先行, 返回與子表達式匹配的前面位置,從做左到右匹配。
(?<= 子表達式),回顧后發,返回與子表達式匹配的后邊位置,從右到左匹配。
我們可以想象有在模式匹配過程中有一指針標志當前匹配的位置,這樣當子表達式匹配時 預測先行 把指針指到子表達式前邊,回顧后發則為后邊??梢詤⒖忌线叴a。
總結
以上是生活随笔為你收集整理的零宽断言java_正则表达之零宽断言(零宽度正预测先行断言)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java中日期比较方法_在java中进行
- 下一篇: java类加载器 架构 设计_类加载器(