天天看點

EmEditor正規表達式彙總

 正規表達式, 英文 Regular expression, 簡寫Regexes或Regex.

<b>應用概述</b>: 提供與預期的搜尋結果比對的确切文本來進行字元串的搜尋和替換操作, 這種技術不僅僅用于開發領域, 更被內建到一些常見的文本擴充編輯器, 如UltraEdit, Emeditor等. 曆史上第一個實用應用程式是Unix 中的qed 編輯器。

舉一個簡單的類比: 我們對DOS中的通配符”*”和”?”應該很熟悉, 如指令”dir *.exe” 将列出所有字尾名為exe的檔案名. 正規表達式提供的方法與其類似, 而且遠比通配符強大的多.

從某種意義上說, 正規表達式是一種語言, 通過及其簡短的一行代碼即可以高效, 精确的描述要比對的複雜文本, 當然, 它最大的優點也是他最大的缺點: 文法複雜, 建立困難. (熟悉之後就可以忽略後半句了 )

<b>主要應用</b>:

資料驗證; 這是正規表達式在開發中最常見的應用, 通過測試字元串内的模式。來驗證輸入的字元串是否為郵政編碼, 電話号碼, 電子郵件位址, 信用卡号碼等等。

搜尋和替換文本; 用正規表達式來搜尋文檔中的特定文本塊, 根據需要用其他指定的文本塊進行替換。這也是文本編輯中的一個常見應用, 如将網頁中的HTML代碼轉化為UBB代碼.

既然發在『軟體使用』闆, 正規表達式的開發中的應用就不介紹了, 以下僅以EmEditor中的正規表達式來作介紹:

1. 啟用正規表達式

菜單: Search – Find (Replace) – 選中 Use Regular Expressions

2. Emeditor 正則文法

正規表達式是普通字元和元字元組合的一種模式. 它的結構與算術表達式的結構類似, 各種元字元和運算符可以将小的表達式組合起來,建立大的表達式。通過在一對分隔符之間放置表達式模式的各種元件,就可以建構正規表達式。

2.1 普通字元

普通字元是指除了 “.”, “*”, “?”, “+”, “(“, “)”, “{“, “}”, “[", "]“, “^”, “$” 和 “\” 這些特殊字元之外的所有其他字元. 而這些特殊字元也可以通過前面加上”\”字首而變為普通字元. 比如, 搜尋”CCF”即為在文本中比對所有的”CCF”字元串, 搜尋”\[CCF\]“則是在文本中比對所有的”[CCF]“字元串. 簡而言之, 普通字元即為隻比對自身的字元.

2.2 元字元

元字元不比對其自身,它用特殊方式來解析進而實作更多的邏輯功能。正規表達式通過元字元在模式中包含選擇和循環

2.2.1 特殊字元

. 比對除換行符 \n 之外的任何單個字元。

( ) 分組捕獲(子表達式)的開始和結束。可以捕獲子表達式以供以後使用。

[ ] 中括号表達式的開始。

中括号表達式是在方括号内包含一個或多個字元構成的清單的表達式。普通字元在中括号内表示本身,大多數特殊字元在中括号表達式内出現時失去它們的意義。除了轉義字元’\', (要包含’\', 需要使用’\\’) 如: 正規表達式 No [1234] 比對 No 1, No 2, No 3 和 No 4. 如果想在中括号中使用一個範圍作為清單來比對字元,可以用連字元 ‘-’ 将範圍中的開始字元和結束字元分開。單個字元的字元值确定範圍内的相對順序。如: 正規表達式 No [1-4] = No [1234] 注意 1. 開始值的Unicode值必須在結束值Unicode值的前面。 注意 2. [\-]比對連字元’-', 放在中括号清單的開始或結尾也可起到同樣的效果, 如 [-c-f] 比對 c 至 f 的字元和連字元 如果需要比對不屬于清單或範圍内的任何字元,可以在清單開頭加上’^'字首。如: 正規表達式 No [^1-4] 比對 No 5 和更大的編号. 中括号表達式還可進行組合, 如 [A-Za-z0-9] 比對A-Z, a-z, 0-9 的字元

\ 将下一字元标記為特殊字元、文本、反向引用或八進制轉義符。例如,

字元 n 比對字元 n \n 比對換行符 序列 \\ 比對 \ 序列 \( 比對 (

| 替換字元, 對|左右的兩個項分别比對進行選擇。或者說, 就是邏輯的OR的概念

{ } 标記限定符表達式的開始。

(數量)限定字元 限定字元能夠指定正規表達式的某個部分必須出現的次數 * 零次或多次比對前面的字元或子表達式。如,c*f 可以比對 f 和 ccf。* = {0,} + 一次或多次比對前面的字元或子表達式。如,c+f 可以比對 cf 和 ccf,但不比對 f。+ = {1,} ? 零次或一次比對前面的字元或子表達式。如,cc?f 可以比對 cf 或 ccf。? = {0,1} {n} n 是非負整數。正好比對 n 次。如,c{2}f 可以比對 ccf。 {n,} n 是非負整數。至少比對 n 次。如,c{2,}f 不比對 cf,而可以比對 ccccccf。c{1,} = c+。c{0,} = c* {n,m} m 和 n 是非負整數,其中 n &lt;= m。至少比對 n 次,至多比對 m 次。如,c{1,3} 可以比對 ccf 中的cc。c{0,1} 等效于 c?。

2.2.2 控制字元

\a Bell 字元。= 0×07 \f 換頁符比對。= 0x0C \n 換行符比對。= 0x0A \r 比對一個回車符。= 0x0D \t 制表符比對。= 0×09 \v 垂直制表符比對。= 0x0B \e ASCII 換碼字元。= 0x1B \0dd 八進制換碼字元, dd代表八進制數字。 \xXXXX或\x{XXXX} 4位十六進制Unicode字元, XXXX代表十六進制數字。 \cZ Z-’@’ 控制字元Control-Z, Z為大于等與”@”的ASCII字元

2.2.3 換碼字元

\w 任一單詞字元, 如A-Z, a-z, 0-9, _等, 如 \w\w\w可以比對 U_4 但不比對 %^e \W 任一非單詞字元, 如 \W\W 可以比對 *&amp; 但不比對 7# \s 任一空白字元,包括空格、制表符、換頁符、回車符和垂直制表符。= [ \f\n\r\t\v] \S 任一非空白字元. = [^ \f\n\r\t\v] \d 0-9的任一數字字元, 如 \d\d可以比對 54 但不比對 a4 \D 任一非數字字元. 如 \D\D可以比對 a4 但不比對 54 \l a-z 之間的任一小寫字元, 如 \l\l\l可以比對 ccf 但不比對 ccF \L 任一非小寫字元, 如 \L\L\L可以比對 CCF 但不比對 cCF \u a-z 之間的任一大寫字元, 如 \u\u\u可以比對 CCF 但不比對 CCf \U 任一非大寫字元, 如 \U\U\U可以比對 ccf 但不比對 ccF \C 任一字元, = ‘.’ \Q 前置引号符, 其後的任意字元均被認為普通字元直至出現後置引号符\E. 同時比對單引号和雙引号 \E 後置引号符

2.2.4 轉義字元串

表示為[:classname:], 如”[[:space:]]”表示所有的空格字元

alnum 任一單詞字元和數字字元. = [\w\d] alpha 任何一個單詞字元, 如A-Z, a-z, 0-9 blank 任一空白字元,包括空格、制表符、換頁符、回車符和垂直制表符。= [ \f\n\r\t\v] = \s cntrl 任一控制字元. digit 0-9的任一數字字元, = \d graph 任一圖形字元. lower a-z 之間的任一小寫字元 =\l print 任一可列印字元 = ‘.’ = \C punct 任一标點符号 space 任一空格字元 upper a-z 之間的任一大寫字元 = \u xdigit 4位十六進制Unicode字元, = \xXXXX word 任何一個單詞字元, 如A-Z, a-z, 0-9, _等, = \w unicode 任何一個ASCII值大于255的字元

2.2.5 定位字元

定位字元可以把正規表達式固定到行首或行尾。在Perl正則全集中還能使正規表達式出現在一個單詞内、在一個單詞的開頭或者一個單詞的結尾, emeditor隻是一個子集, 不包含這個功能。

^ 比對輸入字元串開始的位置。如果設定customize中的”regular expressions can match new line characters”,那麼 ^ 還比對 \n 或 \r 後面的位置。 但在中括号表達式中使用的情況除外,在那種情況下它對字元集求反。 $ 比對輸入字元串結尾的位置。如果設定customize中的”regular expressions can match new line characters”,那麼 $ 還比對 \n 或 \r 前面的位置。

3. 分組捕獲和替換

分組通常用來捕獲特定模式的一組文本, 并用與之後的替換操作, 這也就是将分組和替換結合起來講解的原因.

最基本的分組構造方式就是(),在左右括号中括起來的部分,就是一個分組;在正則全集中還有如(?&lt;name&gt; )的命名分組方式,這種方式組合了模式在就是對分組的部分進行了命名,這樣就可以通過該組的命名來擷取資訊, 但這種方式在emeditor中不被支援. 以下分别來介紹各種不同的分組:

() <b>組捕獲</b>. 這種分組對模式在括号内所捕獲的字元進行組合, 并且每個分組捕獲的比對結果都将儲存為一個實體以備其後的操作所引用. 甚至在正則全集中還可對前面的分組進行反向引用(這是題外話, emeditor不支援). 舉例說明: 源文本: 代碼: 1 site status- online members: 65, online guests: 12 使用正規表達式: (members|guests): \d+ 括号中有兩個可能的比對: members 和 guests, 隻需要比對其中任意一個; 其後是冒号和一個空格, 最後比對至少一個數字. 比對模式結果如下: 2 members: 65 guests: 12 其中members和guests在兩次比對中被捕捉, 可以在随後的操作中引用. (? <b>非組捕獲</b>. 這種分組僅僅對模式在括号内所比對的字元進行組合, 模式所比對的字元将不會作為一個組來捕獲. 雖然他也同樣成為最終的比對結果的一部分, 但無法為其後的操作所引用. 同樣以上例繼續: (?:members|guests): \d+ 比對模式結果同樣為: 但是members和guests僅僅在兩次比對中被分組, 并不被捕獲, 也不可以在随後的操作中引用. 使用非捕獲組有其原因和場合. 其一, 從效率上說, 捕獲一個分組需要消耗額外的資源和處理時間, 是以不應該捕獲不需要使用的資料. 其二, 對模式中有多個捕獲組的情況, 對不需要處理的分組進行捕獲隻會對分組資訊造成混亂. 其三, 避免不需要貪婪比對的場合發生貪婪比對, 貪婪比對是正則引擎的一個重要特性, 要說清楚其機理可能還需要另外開一個專題了. 對這一點, 還以上例說明一下: 使用不帶分組的正規表達式: members|guests: \d+ 比對模式為: members 這個正規表達式的問題在于, 他比對的是”members” 或 “guests: \d+”, 這是模式中貪婪”消費”字元引起的. 而通過增加括号進行分組, 使正則引擎将兩個比對選項作為一個組處理, 進而正确比對其中的一個比對項. (?=) <b>正聲明組, 非捕獲</b>. 此分組中的模式必須出現在聲明的右側, 并且, 這個模式不構成比對結果的一部分. 舉例: \S+(?=\s\d+) 此模式中規定了\s\d+必須出現在\S+聲明的右側. 也就是說, 在至少一個非空格字元(聲明)的右側必須出現一個空格字元和至少一個數字, 而且隻有這個聲明構成比對結果. 比對模式結果如下: members: guests: 這兩次比對中不被捕捉. (?!) <b>負聲明組, 非捕獲</b>. 此分組中的模式不得出現在聲明的右側, 并且, 這個模式不構成比對結果的一部分. 還是用上面的例子: \d{2}(?!,) 此模式中規定了”,”不得出現在\d{2}聲明的右側. 也就是說, 在連續兩個數字(聲明)的右側不得出現逗号才能被比對. 比對模式結果如下: 12

嚴格的說, 後面兩個分組不能稱之為分組, 他們隻是模式聲明, 他們不能成為比對結果, 也不能被捕獲. 在正則全集中, 還有反向聲明分組(?&lt;=)(?), 在emeditor中不被支援.

說到括号的功能, 本來正則中的一個重要指令-條件指令和分組内聯設定是不得不說的, 可惜的是… emeditor也同樣不支援~~~~

在前面的例子中一直提到比對之後的操作, 而這個進一步的操作最常見的就是替換. 先繼續上面的例子:

使用搜尋正規表達式:

(members|guests)

和替換正規表達式:

ccf-\1

比對模式結果如下:

guests

替換後的文本為:

site status- online ccf-members: 65, online ccf-guests: 12

其中members和guests在兩次比對中被捕捉, 在随後被引用, 并添加ccf-字首後替換源文本中的比對字元.

在比對模式中的分組比對結果将按前後順序被正則引擎分别賦予内部組号, 在替換操作中就可以用\加上這個組号來引用相應的比對結果. 繼續上例:

(members|guests): (\d{2})

ccf-\1 = \2

site status- online ccf-members = 65, online ccf-guests = 12

在emeditor的正則子集中增加了一個特殊的引用: \0 , \0 将引用上次的比對結果, 繼續把:

\d{2}

*\0*

65

site status- online ccf-members: *65*, online ccf-guests: *12*

作為一個編輯軟體, emeditor的正則子集中增加了一些替換修飾符:

\U 大寫修飾. 将其後的所有的字元替換為大寫 \L 小寫修飾. 将其後的所有的字元替換為小寫 \H 半角修飾. 将其後的所有的字元替換為半角字元. 寫到這裡, 不得不稱許一下emeditor對中文的良好支援, 這個\H至少我是很常用的, 不喜歡看到文本裡面都是些123abc之類的全角字元… \F 全角修飾. 将其後的所有的字元替換為全角字元 \E 關閉之前的\U, \L, \H, \F修飾. 以下是一些比較有用的正規表達式: ^[  \t]*\n 這個正規表達式代表所有的空行,指含有零個或零個以上空格或制表符、以換行符結尾、不含其它字元的行。 (^|(?&lt;=中國)).*?(?=中國|$) 用正規表達式比對特定字元串外的所有字元。指除“中國”外的所有其它字元,類似于反選功能。 ^[  \t]+ 查找以上字元,并替換為空,可删除行首空白(包括全半角空格和制表符)。 [  \t]+$ 查找以上字元,并替換為空,可删除行末空白(包括全半角空格和制表符)。 ^[  \t]+|[  \t]+$ 查找以上正規表達式,并替換為空,可删除行首和行末所有空白(包括全半角空格和制表符)。 比對中文字元的正規表達式: [\一-\龥] 評注:比對中文還真是個頭疼的事,有了這個表達式就好辦了 比對雙位元組字元(包括漢字在内):[^\x00-\xff] 評注:可以用來計算字元串的長度(一個雙位元組字元長度計2,ASCII字元計1) 比對空白行的正規表達式:\n\s*\r 評注:可以用來删除空白行 比對HTML标記的正規表達式:&lt; (\S*?)[^&gt;]*&gt;.*?|&lt; .*? /&gt; 評注:網上流傳的版本太糟糕,上面這個也僅僅能比對部分,對于複雜的嵌套标記依舊無能為力 比對首尾空白字元的正規表達式:^\s*|\s*$ 評注:可以用來删除行首行尾的空白字元(包括空格、制表符、換頁符等等),非常有用的表達式 比對Email位址的正規表達式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)* 評注:表單驗證時很實用 比對網址URL的正規表達式:[a-zA-z]+://[^\s]* 評注:網上流傳的版本功能很有限,上面這個基本可以滿足需求 比對帳号是否合法(字母開頭,允許5-16位元組,允許字母數字下劃線):^[a-zA-Z][a-zA-Z0-9_]{4,15}$ 比對國内電話号碼:\d{3}-\d{8}|\d{4}-\d{7} 評注:比對形式如 0511-4405222 或 021-87888822 比對騰訊QQ号:[1-9][0-9]{4,} 評注:騰訊QQ号從10000開始 比對中國郵政編碼:[1-9]\d{5}(?!\d) 評注:中國郵政編碼為6位數字 比對身份證:\d{15}|\d{18} 評注:中國的身份證為15位或18位 比對ip位址:\d+\.\d+\.\d+\.\d+ 評注:提取ip位址時有用 比對特定數字: ^[1-9]\d*$    //比對正整數 ^-[1-9]\d*$   //比對負整數 ^-?[1-9]\d*$   //比對整數 ^[1-9]\d*|0$  //比對非負整數(正整數 + 0) ^-[1-9]\d*|0$   //比對非正整數(負整數 + 0) ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$   //比對正浮點數 ^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$  //比對負浮點數 ^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$  //比對浮點數 ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$   //比對非負浮點數(正浮點數 + 0) ^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$  //比對非正浮點數(負浮點數 + 0) 評注:處理大量資料時有用,具體應用時注意修正 比對特定字元串: ^[A-Za-z]+$  //比對由26個英文字母組成的字元串 ^[A-Z]+$  //比對由26個英文字母的大寫組成的字元串 ^[a-z]+$  //比對由26個英文字母的小寫組成的字元串 ^[A-Za-z0-9]+$  //比對由數字和26個英文字母組成的字元串 ^\w+$  //比對由數字、26個英文字母或者下劃線組成的字元串 評注:最基本也是最常用的一些表達式  ^.*John.*$ 比對包括“John”的整行。  private long contract_id; private string contract_number; private string customer_name; “老師說符合編碼規範的代碼要這個樣子才行。” private long contractId; private string contractNumber; private string customerName; “嗯……這也不難,用正規表達式查找替換一下就行啦。”,Clark道。 “我也想過這招,可是用查找和替換最多隻能把那個下劃線去掉,并不能把小寫的字母變成大寫的啊?”老婆大人要急死了。 Clark微微笑道:“别急,面包會有的,小寫也能變成大寫的……” 在老婆大人撲過來之前,Clark以迅雷不及掩耳盜鈴之勢如破竹籃打水的速度打開了EmEditor,輸入查找正規表達式【_(\w)】和替換表達式【\U\1\E】。“\1”表示查找表達式中的第一對“()”裡的内容。 本文轉自孤舟夜航之家部落格51CTO部落格,原文連結http://blog.51cto.com/cysky/1093275如需轉載請自行聯系原作者 cysky

繼續閱讀