Perl 常用的regexp 規則列表 - 朝陽科技大學

文章推薦指數: 80 %
投票人數:10人

Perl 常用的regexp 規則列表. 我們小時候學中文, 從來就不是從文法學起, 而是聽說讀寫很多例句, 腦中自然歸納出一些(可能自己都說不太上來的) 規則。

regexp regexp 簡介 反白練習 網頁書單 誰常上機 規則列表 更多範例 無所不在 簡單例子 資料繪圖 網路應用 light dark 我的部落格: 人權 玩具 快速跳到: 社群活動 本層目錄 上層目錄 此頁@朝陽 此頁@資管 English Perl常用的regexp規則列表 我們小時候學中文,從來就不是從文法學起,而是聽說讀寫很多例句, 腦中自然歸納出一些(可能自己都說不太上來的)規則。

聽說這樣的學習方式比較自然,效果比較好;當然, 花費的時間也相對較長。

筆者那個年代,英文是從國中才開始學起, 已經不像小朋友有那麼充裕的時間。

因此老師/課本/參考書免不了要幫我們整理文法以加速學習:什麼八大詞類, 直述句/疑問句,假設語氣,從屬子句,...等等。

如果您還記得「長線投資的電腦學習策略」裡面提到: 今日的資訊教育實在應該以英文數學教育為師, 就能理解為什麼要談這些了。

筆者認為像是regexp 及命令列這類東西具有長遠投資價值, 但因為要記的文字內容較多而稍嫌困難, 應該可以用學中文的方式來教/學。

所以前兩篇的重點不在有系統/有組織, 而在令讀者熟悉/培養感覺。

不過regexp較之中英文,簡單很多, 如果想把重要的符號及語法用有系統/有組織的方式列出來, 其實也並不會太嚇人。

這篇的目的就是要給那些與我學英文有相同 (不太好的?)習慣,迫不及待想看清楚規律的讀者看的。

但請記住: 沒有看過例子的規則,其實都不算真的學過。

所以看這篇時, 請把它當做像英文文法書一樣,用來複習/預習/查詢, 並且在腦中多回想/設想例子;請不要認真地死背所有規則。

有些沒有教過的東西,後面的章節會詳述。

一、常用符號 常用的regexp符號可以大致分為三類: 比對「一個字元」的符號: [...]...當中任何一個字元 [^...]除了... 之外的任何一個字元 .任何一個字元 具有「定位」功能,但本身不吃掉任何字元的anchor: ^...以...開頭的字串 ...$以...結尾的字串 \b文數字/非文數字的邊界。

計數用,表達「前面的樣版重複出現多少次」的 quantifier: {5}重複5次 {3,7}重複3到7次 {3,}重複至少3次 ?可有可無。

相當於{0,1} *重複出現任意次,包含0次。

相當於{0,} +重複出現任意次,至少1次。

相當於{1,} 所謂「前面的樣版」可能是一個字元, 也可能是由小括弧括起來的一長串 Quantifiers有"不貪婪版本":例如+?是+的"不貪婪版"; *?是*的"不貪婪版"。

小括弧(...) 有三個常用的效果:第一, 它讓quantifier可以作用在一串符號上, 而不只是作用在一個字元上。

第二,小括弧裡面可以用| 切成幾段,表達「這個字串或那個字串」。

(...|...|...)可以說是 [...]的升級版。

第三,小括弧裡面的東西,可以用$1、$2撈出來用。

(下詳) 二、為何選perl? 我們之所以選擇perl來教regexp,有好幾個原因。

第一,perl 有一個很容易記的規則:凡是標點符號,加上倒斜線, 一定沒有特殊意義。

像grep或sed的regexp 就有點複雜。

(所以我用grep時,喜歡用 grep-P...採用perl相容模式, 腦袋比較不會打結。

) 第二,perl替最常用的[...] 定義了簡寫: \d其實就是[0-9], "任何一個數字" \D其實就是[^0-9], "任何一個非數字" \w其實就是[a-zA-Z0-9_], "任何一個文數字" \W其實就是[^a-zA-Z0-9_], "任何一個非文數字" \s其實就是[\t\n], "任何一個空白類字元" \S其實就是[^\t\n], "任何一個非空白類字元" 這裡有關\w與\W的說明並不嚴謹.若要處理英文以外的西方語言, 請參考perlre(1)與perllocale(1)。

第三,後來很多其他軟體都宣告支援PCRE, 也就是Perl-CompatibleRegularExpressions, 可以說perl的regexp已成為軟體界共同的標準。

第四,請見下一節。

三、三種常用句型 perl的彈性很大,小小的變化就可以造出三種不同的句型, 應付常用的搜尋/代換工作(實際上 一句perl能夠寫出的簡單變化還多得是; 不過為了怕嚇到讀者,筆者必須克制一下,就此打住): 搜尋,並印出整列:perl-ne'printif/.../'(簡略寫法) 或是正式寫法:perl-ne'printifm/.../'(m表示"match"比對) 效果約略等同於grep-P'...' 這裡的-P就是perl-compatible的意思。

搜尋,精確列印(不要前後文):perl-ne'print"$1\n"if /..(..)../'效果約略等同於grep-Po'..' (但grep無法print指定僅印比對字串的一小部分) 代換:perl-pe's/.../.../g' 效果約略等同於sed's/.../.../g'。

但sed不支援PCRE,所以我只有很簡單的情況才用sed。

這裡的$1表示"第一對小括弧裡面的東西",$2,$3,...類推。

在"搜尋,精確列印"句型,及"代換"句型當中, 可以用來指稱比對到的字串的一部分,再把它的變形印出來。

例如ip.txt 這個文字檔記錄了一些套件的大小,類別,名稱三個欄位的資訊。

想把第二與第三個欄位對調過來,可以用"搜尋,精確列印"句型: perl-ne'print"$1$3$2\n"if/(\W+)\s+(\W+)\s+(\W+)/' ip.txt也可以用"代換"句型: perl-pe's/(\W+)\s+(\W+)\s+(\W+)/$1$3$2/' ip.txt當然如果資料有點不整齊,像這樣,那就只能用"代換"句型了。

四、其他常用技巧 在比對語法m/.../或代換語法s/.../.../ 後面,都可以加上一些選項,微調比對或代換的效果: i忽略大小寫(ignore) g整列全面代換(global) 如果你的regexp裡面正好用到/那麼也可以改用其他符號作為分隔符號, 但這時代表「比對字串」的m就不能省略。

例如m#...# 或s|...|...|也都可以。

五、進階:段落模式 通常regexp以列為單位在處理資料。

如果每一筆資料橫跨好幾列,那就要用-000選項叫 perl進入「段落模式」(paragraphmode), 把資料視為「以空白列分隔的許多段落」。

準備資料時,要在段落之間插入空白列; 同一段落的資料裡面不能有空白列。

在這個模式下,.不會比對到換列字元。

如果希望它比對到換列字元,需要加上s選項。

在這個模式下,^跟$分別比對到「整段的頭」跟「整段的尾」。

如果希望它們比對「一列的頭」跟「一列的尾」,需要加上m選項。

本頁最新版網址: https://www.cyut.edu.tw/~ckhung/b/re/rules.php; 您所看到的版本:August30201807:24:37. 作者:朝陽科技大學資訊管理系洪朝貴 寶貝你我的地球,請 減少列印,多用背面,丟棄時做垃圾分類。

本文件以 CreativeCommonsAttribution-ShareAlikeLicense 或以 FreeDocumentLicense方式公開授權大眾自由複製/修改/散佈。



請為這篇文章評分?