本網站的更多內容 |
簡介 |
正則表達式快速入門 |
正則表達式教學 |
替換字串教學 |
應用程式和語言 |
正則表達式範例 |
正則表達式參考 |
替換字串參考 |
書籍評論 |
可列印 PDF |
關於本網站 |
RSS 資訊和部落格 |
遞迴簡介顯示 a(?R)?z 如何比對 aaazzz。量詞 ?使前一個代幣成為選用。換句話說,它重複代幣 0 到 1 次。在 a(?R)?z 中,(?R) 由其後面的 ? 變成選用。您可能會疑惑,為什麼正則表達式嘗試遞迴三次,而不是一次或根本不嘗試。
原因是,在遞迴時,正則表達式引擎會重新開始嘗試整個正則表達式。除了引擎會在字串中前進之外,所有量詞和選項的行為就像遞迴之前的比對程序從未發生過一樣。正則表達式引擎會在退出遞迴時還原所有量詞和選項的狀態,無論遞迴是否比對成功。基本上,比對程序會正常繼續,就像遞迴從未發生過一樣,除了引擎會在字串中前進之外。
如果您熟悉程序設計語言,正則表達式遞迴基本上是一個遞迴函式呼叫,而量詞是函式中的局部變數。函式的每個遞迴都會取得自己的局部變數集,這些變數不會影響堆疊中較高層級的遞迴中的相同局部變數,也不會受到這些變數影響。遞迴中的量詞在所有版本中都是這樣運作的,Boost 除外。
讓我們看看 a(?R){3}z|q 的行為(Boost 除外)。最簡單的可能配對是 q,由正規表示式的第二個選項找到。
第一個選項配對的最簡單配對是 aqqqz。在 a 配對後,正規表示式引擎開始遞迴。 a 無法配對 q。引擎仍在遞迴中,嘗試第二個選項。 q 配對 q。引擎以成功的配對退出遞迴。引擎現在注意到量詞 {3} 已成功重複一次。它需要再重複兩次,因此引擎開始另一個遞迴。它再次配對 q。在量詞的第三次迭代中,第三次遞迴配對 q。最後,z 配對 z,找到整體配對。
這個正規表示式不配對 aqqz 或 aqqqqz。 aqqz 失敗,因為在量詞的第三次迭代中,遞迴無法配對 z。 aqqqqz 失敗,因為在 a(?R){3} 已配對 aqqq 之後,z 無法配對第四個 q。
正規表示式可以配對較長的字串,例如 aqaqqqzqz。對於這個字串,在量詞的第二次迭代中,遞迴配對 aqqqz。由於每個遞迴都分別追蹤量詞,因此遞迴需要連續三次遞迴才能滿足量詞的自身實例。這可能導致任意長的配對,例如 aaaqqaqqqzzaqqqzqzqaqqaaqqqzqqzzz。
Boost 對量詞在遞迴中的運作方式有自己的想法。遞迴僅在 Boost 中與其他版本中相同,如果遞迴運算子完全沒有量詞,或者如果它有 * 作為其量詞。任何其他量詞都可能導致 Boost 1.59 或更早版本與 Boost 1.60 及更高版本相較於其他正規表示式版本有非常不同的配對(或缺乏配對)。Boost 1.60 嘗試修復 Boost 和其他版本之間的一些差異,但它只導致不同的不相容行為。
在 Boost 1.59 及之前版本中,遞迴量詞會計算整個遞迴堆疊中的迭代和遞迴次數。因此,在 Boost 1.59 中,a(?R){3}z|q 的可能匹配項包括 aaaazzzz、aaaqzzz、aaqqzz、aaqzqz 和 aqaqzzz。在所有這些匹配項中,遞迴和迭代的次數加起來等於 3。其他版本不會找到這些匹配項,因為它們需要在每次遞迴期間進行 3 次迭代。因此,其他版本可以匹配類似 aaqqqzaqqqzaqqqzz 或 aqqaqqqzz 的字串。Boost 1.59 僅會在這些字串中匹配 aqqqz。
Boost 1.60 嘗試像其他版本一樣在每個遞迴層級迭代量詞,但執行方式不正確。任何使遞迴為可選的量詞都允許多次重複。因此,Boost 1.60 和更新版本會將 a(?R)?z 視為與 a(?R)*z 相同。雖然這修正了 a(?R)?z 在 Boost 1.59 中無法完全匹配 aaazzz 的問題,但它也允許其他版本無法使用此正規表示式找到的匹配項,例如 aazazz。如果量詞不是可選的,則 Boost 1.60 僅允許它在第一次遞迴期間匹配。因此,a(?R){3}z|q 只能匹配 q 或 aqqqz。
Boost 在遞迴量詞上的問題也會影響遞迴標記的父群組上的量詞。它們也會影響子常式呼叫上的量詞,以及包含子常式呼叫到具有量詞的群組的父群組的群組上的量詞。
正規表示式中其他標記上的量詞在遞迴期間會正常運作。它們會在每次遞迴中分別追蹤其迭代。因此,a{2}(?R)z|q 會匹配 aaqz、aaaaqzz、aaaaaaqzzz 等。在每次遞迴期間,a 都必須匹配兩次。
像這樣位於遞迴中但不會重複遞迴本身的量詞在 Boost 中確實可以正確運作。
| 快速入門 | 教學課程 | 工具與語言 | 範例 | 參考 | 書籍評論 |
| 簡介 | 目錄 | 特殊字元 | 非列印字元 | 正規表示式引擎內部 | 字元類別 | 字元類別減法 | 字元類別交集 | 簡寫字元類別 | 點 | 錨點 | 字詞邊界 | 交替 | 可選項目 | 重複 | 群組和擷取 | 反向參照 | 反向參照,第 2 部分 | 命名群組 | 相對反向參照 | 分支重設群組 | 自由間距和註解 | Unicode | 模式修改器 | 原子群組 | 獨佔量詞 | 前瞻和後顧 | 前瞻和後顧,第 2 部分 | 將文字排除在比對之外 | 條件式 | 平衡群組 | 遞迴 | 子常式 | 無限遞迴 | 遞迴和量詞 | 遞迴和擷取 | 遞迴和反向參照 | 遞迴和回溯 | POSIX 方括號表示式 | 零長度比對 | 繼續比對 |
頁面網址:https://regular-expressions.dev.org.tw/recurserepeat.html
頁面最後更新時間:2020 年 3 月 30 日
網站最後更新時間:2024 年 3 月 15 日
版權所有 © 2003-2024 Jan Goyvaerts。保留所有權利。