php排除型正則表達式—— 一般排除法 及 斷言(前后瞻斷言)的方式排除 (被查找的內容都是多行跨行的情況) 關於斷言請翻閱 php手冊 · 在索引輸入: preg_xxx · 進入某函數后 · 點擊頂部導航的 PCRE正則語法 · 子組/斷言 閱讀更多內容. (下面所有例子中的#...# , ##僅僅表示使用正則時的一對閉合的分隔符 定界符號,ending delimiter .) 1. 使用一般排除的方法 要求查找到所有的html注釋標簽<!-- ... --> , 但排除script腳本和style樣式內的注釋符<!-- ...... //--> 的正則表達式 代碼如下: <?php $str = '...'; // 請自行輸入帶html注釋的字符串進行測試. $patten_comm = '#<!--[^(?://\-\->)]*?-->#'; // 已排除js或style腳本樣式標簽內的注釋,測試符合要求(也符合換行的情況) preg_match_all( $patten_comm , $str , $res ); echo '<pre>';var_dump( $res );echo '</pre>'; ?> 該正則其中的 (?:) 表示對內容進行分組(表示作為一個整體, 或稱為模組) ,但不要捕獲它們。它跟小括號()的區別是,不能像
小括號()那樣通過在表達式中寫上 \1 的方式, 引用括號里面的內容. 就是說只匹配,不捕獲. 現在我們使用[^(?://-->)] 就表示排除 //--> , 但由於"-"杠號在中括號內有歧義,所以要用\轉義,於是改成: //\-\-> 這樣整個正則表達式就排除了<!-- ... //-->, 而獲取到了正確的結果。 2. 使用前瞻斷言 排除 “前瞻斷言”以符號(?!abc)進行聲明, 其中在括號里面寫上 (?!這里寫上被排除的正則表達式) 的方式進行排除. 舉例1: 排除以xxx為前綴的情況. php手冊上舉例的是 (?!abc)ddd 排除前面是abc的情況,我們用實際應用舉例: 要求: 查找字符串中的php變量$abc,但排除前面是轉義符的情況—— \$abc 對應正則: #(?!\\)\$[a-zA-Z_][a-zA-Z0-9_\-]# 舉例2: 排除以xxx為結尾(后綴)的情況. 在日志文件中,一般每行作為一條記錄,我們要列出所有的 以行為單位的日志,但不要包括那些機器人的情況,即排除以robots結尾的情況。(此例子系引用他人) 對應正則: ^(?!.*?robots).*$ 該正則通過排除整個 .*robots 的方式,以達到排除以robots結尾的情況,而同時又能捕獲那些不是robots結尾的文本。 3. 使用 后瞻斷言 排除 后瞻斷言是以 (?>! 排除內容) 為聲明表示. php手冊上的例子是: (?<!foo)bar 用於查找任何前面不是”foo”的”bar”. 后瞻斷言的內容,被嚴格限制為只能使用固定長度的字符串. 也就是不能是 (?<!end.*) 這種任意長度的, 必須是固定的, 否則php會報這個錯誤:Compilation failed: lookbehind assertion is not fixed length 。 后瞻斷言本人使用不多,就不詳述了。
例子:
要求:匹配除了 <a>標簽之內的,所有"test"字符
aaaaatestaaa<a href="test" class="aaaaa" title="oooo">aatestaaaaaa</a>aaaatestaaaa
正則表達式:(?<!<[^>]*)test(?![^<]*</a>)
結果:( C#測試 )
