正規表示式如何處理巢狀結構

2022-04-05 18:50:57 字數 2839 閱讀 2042

1, 正規表示式如何處理巢狀結構

a..net處理巢狀結構的方法

舉例說明:

問題描述:從before (nope (yes (here) okay) after中匹配得到最大的被」()」包含的文字。即顯示紅色的部分。

答案:.net:

"((?>[^()]+|"((?)|")(?))*(?(depth)(?!))")

分析:(1)、

"(匹配左括號;

")匹配右括號;

[^()]+

匹配非括號字串

(2)、

(?>….)

固化分組,固化分組的作用在於:一旦括號內的子表示式匹配之後,匹配的內容就固定下來,在接下來的匹配過程中不會改變,除非整個固化分組的括號都被棄用,在外部回溯中重新應用。該處使用固化分組的作用在於提高匹配速度。

(3)、depth的使用:depth實際使用了命名捕獲的

>…>,它總是能夠匹配成功。正規表示式引擎的回溯堆疊儲存了當前匹配成功分組的相關資訊,而

(?)跟在

"(後,所以它的成功匹配便可以儲存

"(的個數。跟隨在

")後的結構

(?)是.net獨有的結構,它會在匹配

")成功之後去掉最近的」successful depth」標記。如果不存在這樣的」successful depth」標記,就會報告失敗,整個正規表示式匹配失敗:1,每匹配乙個

"(會把正規表示式儲存的當前括號巢狀深度值加1;2, 每匹配乙個

")會把正規表示式儲存的當前括號巢狀深度值減1;3,(?(depth)(?!))

確保匹配最後的

")時,深度為0。

2, 如何使用正規表示式處理句法分析樹

如何使用正規表示式識別一棵類似如下表示的句法分析樹?

(top (s (npb (dt the) (nn question) ) (vp (vbz remains) (sbar-a (in whether) (s-a (npb (prp they) ) (vp (md will) (vp-a (vb be) (adjp (jj able) (sg (vp (to to) (vp-a (vb help) (punc. us.) ) ) ) ) ) ) ) ) ) ) )

答案:"((?>[^()]+|"([^()"s]+"s(?)|")"s(?))*(?(depth)(?!))")

分析類似。

3, 使用正規表示式處理句法分析樹例項

a.使用正規表示式獲取所有的葉結點:    "((?[^()]+)"s(?[^()]+)")

b.使用正規表示式獲取所有的名詞短語np:

"(np"s(?>[^()]+|"([^()"s]+"s(?)|")"s(?))*(?(depth)(?!))")

c.使用正規表示式獲取滿足如下性質的子樹

i.該子句的標記為

sbar[^()]*

ii.該子句根節點的第乙個兒子為乙個詞性為in的詞。

iii.

該子句的第二個兒子為乙個子句:使用

s[^()]*

識別iv.

該子句沒有其他的兒子

(?"(s[^() ]*"s(?"(in"s[^()]+")"s)(?"(s[^() ]*"s(?>[^()]+|"([^()"s]+"s(?)|")"s(?))*(?(depth)(?!))")"s)")"s(?#clause)) 在開發模板引擎時遇到了乙個用正規表示式比較難以處理的情況,就是無限級的巢狀結構的匹配。html標籤就屬於這種結構。

舉個具體的例子,下面是我們要匹配的內容:

123

45

>

>

>

>

>

>

>

>

在找到用正則匹配無限層巢狀結構的方法之前,我只能繞彎路來實現對無限層巢狀結構的匹配。

我只能用正則先把每個獨立的標籤匹配出來,然後用第乙個標籤名x做引數,逐一的查詢匹配出來的每乙個獨立標籤,看看他是否是第乙個x對應的閉合標籤。

這種方式得加上判斷巢狀層次的**,還得匹配和迴圈很多沒有用的資料。

後來我才了解到.net提供了乙個正規表示式的擴充套件特性,用來幫助處理無限層巢狀結構的匹配。這種特性是.net特有的,別的程式語言或者平台不一定會有。

我們都知道正則的匹配組的概念,它的語法是 (?《組名》)。使用這個正則語法我們可以建立乙個匹配組。其實這是乙個入棧的過程。

而.net對正則的匹配組做了乙個特殊的支援 (?

乙個入棧乙個出棧,這一入一出就為我們提供了匹配無限層巢狀的可能

下面舉個例子看看怎麼實現無限層巢狀的匹配:

從圖中我們可以看出正則正確的匹配出了最頂層的三個結構,而巢狀在第二個結構中的標籤被當成了結構的內容。這是怎麼做到的呢?

下面是圖中的正則,我加入了注釋:

123

4567

89

10

(?>

(?) #在匹配到時,將匹配組n入棧

|(?) #在匹配到時,將匹配組n出棧

|(?!|). #匹配除和以外的其他字元

)*(?(n)(?!)) #如果執行到此處還存在匹配組n,則匹配失敗,重新匹配

這段正則中還用到了平時比較少使用到的(?!(name)yes|no)語法,這個語法相當於c語言的if語法,用於做條件判斷,之用。上面的正則中我們用它來片段是否存在命名組n,如果存在命名組n,說明標記沒有對稱閉合,用(?!)斷言匹配失敗,重新匹配。

在《mastering regular expressions》中似乎有相關章節提到這種無限層巢狀結構的匹配,不過我手頭沒這本書。我是從這裡學習到這種特殊的正則語法的,大家可以參考下

js如何處理正規表示式中匹配的內容

有時候需要實現乙個功能,使得資料以不同的方式顯示,好像有點說不清楚,舉個例子吧。比如 給定乙個包含了所有課程的資料,在a頁面上是一種排版方式,在b頁面上是另外一種排版方式,這時候可以採用模板的方式將資料渲染到頁面上。但是這就涉及到乙個模板的建立和解析的問題。我這裡自定義了在html標籤中嵌入變數的方...

如何匹配巢狀Html標籤 正規表示式

概述 正規表示式是做文字解析工作必不可少的技能。如web伺服器日誌分析,網頁前端開發等。很多高階文字編輯器都支援正規表示式的乙個子集,熟練掌握正規表示式,經常能夠使你的一些工作事半功倍。例如統計 行數,只需乙個正則就搞定。巢狀html標籤的匹配是正規表示式應用中乙個比較難的話題,因為它涉及到的正則語...

正規表示式相關 正規表示式處理html內容

前面關於顯示html文字用了瀏覽器控制項來處理 這個不過是為了解決燃眉之急不得已才使用。其實最好還是使用正規表示式處理,也就是自己寫乙個html文字直譯器,當然這個實現起來也是不容易的,首先你得將所有html文字標籤羅列出來,然後一一翻譯。下面先搞乙個簡單的例子吧。public static str...