亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

深入入門正則表達式(java) - 匹配原理 - 1 -

系統 1941 0

深入入門正則表達式(java) - 引言

深入入門正則表達式(java) - 1 - 入門基礎 ?
深入入門正則表達式(java) - 2 - 基本實例

深入入門正則表達式(java) - 3 - 正則在java中的使用

深入入門正則表達式(java) - 匹配原理 - 1 - 引擎分類與普適原則

深入入門正則表達式(java) - 匹配原理 - 2 - 回溯

?

?

本節第一部分主要介紹正則引擎的分類, 由于java屬于NFA,所以只重點介紹此類。其余類型簡要或不做介紹。

分類的內容全部來自《精通正則表達式》v3

?

引擎類型 程序
DFA awk(大多數版本)、egrep(大多數版本)、flex、lex、MySQL、Procmail
傳統NFA GNU Emacs、Java、grep(大多數版本)、less、more、.NET語言、PCRE library、Perl、PHP(所有三套正則庫)、Python、Ruby、sed(大多數版本)、vi
POSIX NFA mawk、Mortice Kern Systems'utilities、GNU Emacs(明確指定時使用)
DFA/NFA混合 GNU awk、GNU grep/egrep、Tcl

?

NFA(非確定型有窮自動機):表達式主導

正則:“to(nite|knight|night)”

目標文本:“tonight”

正則表達式從“t”開始,每次檢查一部分(由引擎查看表達式的一部分),同時檢查當前文本是否匹配表達式的當前部分。如果是,則繼續表達式的下一部分,直到表達式的所有部分都能匹配。

此例中第一個元素是“t”,它會重復嘗試,在目標字符串中找到“t”為止,然后檢查“o”,過程與此一致。然后是“(nite|knight|night)”部分,表達式會一次嘗試, 直到宣告匹配成功或失敗才會停止。 表達式中的控制權在不同元素之間轉換,所以作者稱其為“表達式主導”

所以正則:“nfa|nfa not”,目標字符串:“nfa not”中,也只是匹配“nfa”而已,而不會完整的匹配。

?

DFA (確定型有窮自動機) :文本主導

DFA引擎在掃描字符串時,會記錄“當前有效”的所有匹配可能。

還是最初的例子,引擎移動到“t”時,它會在當前處理匹配可能中添加一個潛在的可能

接下來掃描的每個字符,都會更新當前的可能匹配序列。繼續掃描兩個字符之后的情況如上圖。分支“knight”被排除。

書中作者稱其問文本主導,是因為掃描每個字符的時候都對引擎進行了控制

?

?

測試引擎類型

1.如果支持忽略優先量詞,那么基本就是傳統NFA。DFA不支持忽略優先量詞,POSIX NFA中也沒有意義。

2.DFA不支持捕獲型括號和回溯。在這兩種混合類型的引擎中,如果沒有使用捕獲型括號,就會使用DFA

ps:在RegexBuddy中似乎只有傳統NFA,起碼做1的驗證時結果是這樣的,所以DFA和混合型引擎在這就不做驗證了,本文也主要針對java,所以這里指著重介紹和java相關內容

?

?

?

兩條普適原則 (來自 《精通正則表達式》 v3)

1.優先匹配最左面(最靠開頭)的匹配結果

注意:此原則并沒有規定優先匹配結果的長度,而只是規定在所有可能的匹配結果中,優先選擇最左邊的(可能有)。

作者關于此原則的解釋:匹配先從需要查找的字符串的起始位置嘗試匹配。這里的“嘗試匹配”的意思是:在當前位置測試整個正則表達式能匹配的每個可 能。如果在當前位置測試了所有的可能之后找不到匹配結果,就需要從字符的第二個字符之前的位置開始重新嘗試……只有在嘗試過所有的起始位置(直到字符串的 最后一個字符)都找不到匹配結果的情況下,才會報告失敗。

下面給出一個例子:

目標字符串“This is a cat.”

我想匹配字符“is”,我的正則為“is”

結果如下(圖1):

這里找到了兩個結果,根據原則1,最先找到的是“this”中的“is”,而并沒有找到“is”這個單詞。這也很容易理解。下面我們看看RegexBuddy中debug的過程
深入入門正則表達式(java) - 匹配原理 - 1 - 引擎分類與普適原則

這里怎么會有這么多字符,目標字符串實際只有13個字符,那么多出來的那些都是哪來的呢?

我覺得,RegexBuddy是把字符與字符之間的位置也算為一個character。再來看看圖1

我之所以把每一個字符都裝在表格里,就是讓大家看的清楚。這里,每一個豎線(其實是不存在的)也作為一個character,我覺得這樣是有道理的,比如零寬斷言,它的匹配就是在某一個豎線的位置。我們不妨用“^”測試一下,看看debug的結果。

深入入門正則表達式(java) - 匹配原理 - 1 - 引擎分類與普適原則
深入入門正則表達式(java) - 匹配原理 - 1 - 引擎分類與普適原則

?

當正則以“字符串起始位置錨點”開頭,引擎就會知道如果能匹配,那么肯定是從字符串開頭,所以不需要做更多的嘗試。

ps:這和RegexBuddy上面的debug結果似乎是矛盾的。確實是這樣,不知道是不是其一個bug,起碼v3.5.4是這樣的

RegexBuddy暫時是不支持字符組的集合操作的,不知這算功能缺失還是算個bug

?

?

2.標準的量詞(*,+,?,{m,n})是匹配優先的

目標字符串:“copyright 2003”

正則:“.*”,那么匹配的結果為全部字符

正則:“.*[0-9]*”,這個時候,由于量詞是匹配優先的,所以“.*”會匹配整個字符串,而后面的“[0-9]*”怎什么也匹配不到 ,這并不影響最終結果,因為“*”表示0個也可以,我們可以添加一組括號來驗證這個結果,如下圖顯示的一樣
深入入門正則表達式(java) - 匹配原理 - 1 - 引擎分類與普適原則

我們現在將正則改成這樣:“.*[0-9]+”,這時候“.*”也會先把字符串全部匹配,之后是“[0-9]+”這個部分,發現它要求至少匹配到一 個數字才行,所以它會強迫“.*”吐出它之前匹配到的內容給自己使用,當“.*”吐出字符“3”之后,“[0-9]+”成功匹配,至此匹配結束,不再進行 其他嘗試。

我們來debug看看這一過程:
深入入門正則表達式(java) - 匹配原理 - 1 - 引擎分類與普適原則

書中作者總結為:先來先服務。我覺得,也就是說,多個匹配優先量詞時,如果目標字符串“不能無法同時滿足其需求”,那么寫在前面的量詞會得到盡量多的字符,后面的量詞會像“類似”忽略優先量詞一樣進行匹配 - 給點就行。

?

?

?

?

轉貼請保留以下鏈接

本人blog地址

http://su1216.iteye.com/

http://blog.csdn.net/su1216/

深入入門正則表達式(java) - 匹配原理 - 1 - 引擎分類與普適原則


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 日日添天天做天天爱 | 尹人香蕉网在线观看视频 | 久热中文字幕在线精品首页 | 国产91在线 | 日本 | 午夜在线精品不卡国产 | 天天操婷婷 | 亚洲视频国产精品 | 亚洲成a人v欧美综合天 | 欧美精品一区二区三区久久 | 国内精品久久久久影院中国 | 狠狠澡夜夜澡人人爽 | 精品国产视频在线观看 | 日韩最新中文字幕 | 四虎影视库永久在线地址 | 黄色片网站在线免费观看 | 亚洲国产成人久久一区二区三区 | 操美女的视频网站 | 久草视频中文 | 亚洲天天综合 | 日韩中文字幕视频在线 | 一级毛片免费视频观看 | 国产96福利视频在线观看 | 久久成人国产精品免费 | 一道本不卡免费视频 | 日本视频a | 久热国产精品视频 | 97在线播放 | www.深夜| 久久免费视频网站 | 精品久久久中文字幕二区 | 98色花堂永久地址国产精品 | 美女视频国产 | 美女福利在线观看 | 夜色成人影院在线www | 天天综合在线观看 | avav在线精品 | 亚洲色中文字幕在线播放 | 亚洲精品日韩中文字幕久久久 | 日本高清中文字幕 | 国产成在线人视频免费视频 | 国产产一区二区三区久久毛片国语 |