PHP擴(kuò)展之文本處理(二)——PCRE正則表達(dá)式語法14——注釋及遞歸模式
字符序列(?#標(biāo)記開始一個注釋直到遇到一個右括號。不允許嵌套括號。 注釋中的字符不會作為模式的一部分參與匹配。
如果設(shè)置了?PCRE_EXTENDED?選項(xiàng), 一個字符類外部的未轉(zhuǎn)義的 # 字符就代表本行剩余部分為注釋。
遞歸模式考慮匹配圓括號內(nèi)字符串的問題,允許無限嵌套括號。如果不使用遞歸, 最好的方式是使用一個模式匹配固定深度的嵌套。它不能處理任意深度的嵌套。 perl 5.6 提供了一個實(shí)驗(yàn)性的功能允許正則表達(dá)式遞歸。 特殊項(xiàng) (?R) 提供了遞歸的這種特殊用法。 這個PCRE模式解決了圓括號問題(假設(shè)?PCRE_EXTENDED?選項(xiàng)被設(shè)置了, 因此空白字符被忽略):?( ( (?>[^()]+) | (?R) )* )。
首先,它匹配一個左括號。 然后它匹配任意數(shù)量的非括號字符序列或一個模式自身的遞歸匹配(比如, 一個正確的括號子串),最終,匹配一個右括號。
這個例子模式包含無限重復(fù)的嵌套,因此使用了一次性子組匹配非括號字符, 這在模式應(yīng)用到模式不匹配的字符串時非常重要。比如, 當(dāng)它應(yīng)用到?(aaaaaaaaaaaaaaaaaaaaaaaaaaaaa()?時就會很快的產(chǎn)生”不匹配”結(jié)果。 然而,如果不使用一次性子組,這個匹配將會運(yùn)行很長時間, 因?yàn)橛泻芏嗤緩阶?+ 和 * 重復(fù)限定分隔目標(biāo)字符串, 并且在報(bào)告失敗之前需要測試所有路徑。
所有捕獲子組最終被設(shè)置的捕獲值都是從遞歸最外層子模式捕獲的值。 如果上面的模式匹配?(ab(cd)ef),捕獲子組最終被設(shè)置的值為 ”ef”, 即頂級得到的最后一個值。如果增加了額外的括號,( ( ( (?>[^()]+) | (?R) )* ) ),捕獲到的字符串就是頂層括號的匹配內(nèi)容 ”ab(cd)ef”。 如果在模式中有超過 15 個捕獲括號, PCRE 在遞歸期間就會使用 pcre_malloc 分配額外的內(nèi)存來存儲數(shù)據(jù), 隨后通過 pcre_free 釋放他們。如果沒有內(nèi)存可被分配,它就僅保存前 15 個捕獲括號, 在遞歸內(nèi)部無法給出內(nèi)存不夠用的錯誤。
從 PHP 4.3.3 開始,?(?1)、(?2)?等可以用于遞歸子組。這同樣可以用于命名子組:?(?P>name)?或?(?P&name)。
如果遞歸子組語法在它提到的子組括號外部使用(無論是子組數(shù)字序號還是子組名稱), 這個操作就相當(dāng)于程序設(shè)計(jì)語言中的子程序。 前面一些有一個例子指出模式?(sens|respons)e and 1ibility?匹配 ”sense and responsibility” 和 ”response and responsibility”,但是不匹配 ”sense and responsibility”。如果用模式(sens|respons)e and (?1)ibility?替代, 它會像匹配那兩個字符串一樣匹配 ”sense and responsibility”。 這種引用方式意義是緊接著匹配引用的子模式。(譯注: 后向引用只匹配引用的子組之前匹配的結(jié)果, 這里的遞歸語法引用是拿引用的子模式重新匹配。)
目標(biāo)字符串的最大長度是 int 型變量可以存儲的最大正整數(shù)。然而, PCRE 使用遞歸處理子組和無限重復(fù)。 這就是說對于某些模式可用的棧空間可能會受目標(biāo)字符串限制。
相關(guān)文章:
1. 低版本IE正常運(yùn)行HTML5+CSS3網(wǎng)站的3種解決方案2. xml文件的結(jié)構(gòu)解讀第1/2頁3. jsp實(shí)現(xiàn)局部刷新頁面、異步加載頁面的方法4. Jsp中request的3個基礎(chǔ)實(shí)踐5. vue根據(jù)條件不同顯示不同按鈕的操作6. js中的正則表達(dá)式(一)7. IntelliJ IDEA 2021.1 EAP 4 發(fā)布:字體粗細(xì)可調(diào)整Git commit template 支持8. IntelliJ-Idea導(dǎo)出可執(zhí)行Jar流程解析9. 簡單了解JavaScript作用域10. ASP程序中常用的腳本語言
