From 9b925ef9040a78c945fbadefee509eb67047acbf Mon Sep 17 00:00:00 2001 From: Jericho229 Date: Fri, 18 Dec 2015 10:46:52 +0800 Subject: [PATCH] =?UTF-8?q?Regex=20-=20=E9=97=9C=E6=96=BC=E6=AD=A3?= =?UTF-8?q?=E8=A6=8F=E8=A1=A8=E7=A4=BA=E5=BC=8F=E7=9A=84=E4=B8=80=E9=BB=9E?= =?UTF-8?q?=E7=AD=86=E8=A8=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://blog.hinablue.me/entry/php-note-about-the-regular-expression-in-the-php/ --- Regular Expression | 52 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 Regular Expression diff --git a/Regular Expression b/Regular Expression new file mode 100644 index 0000000..eca238a --- /dev/null +++ b/Regular Expression @@ -0,0 +1,52 @@ +關於正規表示式的一點筆記 +05 MAY 2011 on PHP, Work, Regular Expression, 正規表示式 +我發現我很久沒有寫 PHP 的筆記了,不過因為我本來就不太會寫 PHP,所以文章很少也是很合理的(挺)。這次要筆記的東西是正規表示式,其實網路上文章非常多,我首推這篇:Regular Expression (RegExp) in JavaScript + +疑?怎麼是 Javascript!?哎呀,沒關係啦,其實正規表示式大家都差不多嘛(喂)。但是呢,我這裡筆記的東西請不要直接搬去給 Javascript 用,會出人命的。首先,我要講得東西這邊全部都有: + +PCRE regex syntax + +所以如果英文不錯的人可以直接看官方說明就好。我這裡只是因為英文很爛所以筆記一下而已(無責)。比較基礎就不再贅述了,去問 Google 大神應該可以找到一大堆,倒是,這一篇官方說明可以筆記一下,有一些跳脫的字元可以留意一下,免得誤觸地雷。 + +Escape sequences + +至於 Internal option setting 也請記得,不要誤用。請注意 PCRE_MULTILINE(/^(.*)$/m)的設定,他會讓你的定位結果(使用 ^ 與 $ 時)與其他的設定不同。而,這個設定也可以在 Subpatterns 中使用,使用的方法大概是這樣:(?i: 或是 (?m<= 爾等。 + +接著來提一下 Subpatterns 的作法。在正規表示式中,我們可以依照提取出來的結果,更準確的把我們想要的部份個切割開來。這種時候 Subpatterns 就異常的好用。首先先說明一下我們有哪些工具可用: + +( ) 最常見的括號,代表將內容做一個記憶群組動作。 +(?: ) 與括號作用相同,不同的是,這個群組是不會被記憶的。 +(?| ) 當群組使用多選時,可以避免沒有選中結果,但卻產生空的群組(該群組還會被記憶)。 +(? ) 群組命名,一般正規輸出都是單純陣列,這個命名會是陣列鍵值。 +另外還有比較特殊的用法,稱為右(左)合,右(左)不合的形式,可搭配條件比對使用: + +(?= 左合樣式 +(?<= 右合樣式 +(?! 左不合樣式 +(? 顧名思義就是,我只比對一次。 +還有條件式比對(Conditional subpattern),請搭配左(右)合(不合)樣使用: + +`(?(condition)yes-pattern) 照字面上的意思,就不用多做解釋了吧。 +`(?(condition)yes-pattern|no-pattern) 同上,只是多了個 no-pattern 而已(喂 +然後,既然有群組(不管是否有記憶動作),就能夠拿出來參考(Back references): + +\1 常見用法,將第一個群組拿出來用。 +\g1, \g1, \g{1}, \g{-1} 取出特定群組用法,用大括號有一個特別的地方就是,可以避免一些問題*。 +(?P=name) 遇到有命名的群組,這樣可以把該群組拿出來用。 +舉一個例子,我用顏色區隔應該會比較好理解一點(有嗎?): + +"/(?:(?P(?|_t|_f|_text|_textf))((?P(?|'|\")))(?P +*)?/i" +這是我用來掃描原始碼,當其中有 _t('xxxxx') 或是 _text("xxxxx") 出現時,把 _t 這類的程式名稱命名為 tag,把 ' 或是 " 命名為 quote,然後把程式包的內容命名為 content,其中 content 的內容是非第一記憶群組的所有文字。抓出來就是我要的結果嗎? + +假設變數是這樣: + +$a = '_t("123") _f(\'456\') _text(\'789 "12345" 6789\')'; +其實結果並不如預期,無論在單行或是多行處理時,最後一個條件會符合這種情況: + +_t('123 +_f('456 +_text('789 // 這裡出現斷尾了!