Regex簡介

來源:互聯網
上載者:User
正則

如果原來沒有使用過Regex,那麼可能對這個術語和概念會不太熟悉。不過,它們並不是您想象的那麼新奇。

請回想一下在硬碟上是如何尋找檔案的。您肯定會使用 ? 和 * 字元來協助尋找您正尋找的檔案。? 字元匹配檔案名稱中的單個字元,而 * 則匹配一個或多個字元。一個如 'data?.dat' 的模式可以找到下述檔案:

data1.dat

data2.dat

datax.dat

dataN.dat

如果使用 * 字元代替 ? 字元,則將擴大找到的檔案數量。'data*.dat' 可以匹配下述所有檔案名稱:

data.dat

data1.dat

data2.dat

data12.dat

datax.dat

dataXYZ.dat

儘管這種搜尋檔案的方法肯定很有用,但也十分有限。? 和 * 萬用字元的有限能力可以使你對Regex能做什麼有一個概念,不過Regex的功能更強大,也更靈活。

-------------------------------------------------------
2.早期起源

早期起源

Regex的“祖先”可以一直上溯至對人類神經系統如何工作的早期研究。Warren McCulloch 和 Walter Pitts 這兩位神經生理學家研究出一種數學方式來描述這些神經網路。

1956 年, 一位叫 Stephen Kleene 的美國數學家在 McCulloch 和 Pitts 早期工作的基礎上,發表了一篇標題為“神經網事件的標記法”的論文,引入了Regex的概念。Regex就是用來描述他稱為“正則集的代數”的運算式,因此採用“Regex”這個術語。

隨後,發現可以將這一工作應用於使用Ken Thompson 的計算搜尋演算法的一些早期研究,Ken Thompson是Unix 的主要發明人。Regex的第一個實用應用程式就是 Unix 中的qed 編輯器。

如他們所說,剩下的就是眾所周知的曆史了。從那時起直至現在Regex都是基於文本的編輯器和搜尋工具中的一個重要部分。
--------------------------------------------------------
3.使用Regex

在典型的搜尋和替換操作中,必須提供要尋找的確切文字。這種技術對於靜態文本中的簡單搜尋和替換任務可能足夠了,但是由於它缺乏靈活性,因此在搜尋動態文本時就有困難了,甚至是不可能的。

使用Regex,就可以:

1.測試字串的某個模式。例如,可以對一個輸入字串進行測試,看在該字串是否存在一個電話號碼模式或一個信用卡號碼模式。這稱為資料有效性驗證。

2.替換文本。可以在文檔中使用一個Regex來標識特定文字,然後可以全部將其刪除,或者替換為別的文字。

3.根據模式比對從字串中提取一個子字串。可以用來在文本或輸入欄位中尋找特定文字。

例如,如果需要搜尋整個 web 網站來刪除某些過時的材料並替換某些HTML 格式化標記,則可以使用Regex對每個檔案進行測試,看在該檔案中是否存在所要尋找的材料或 HTML 格式化標記。用這個方法,就可以將受影響的檔案範圍縮小到包含要刪除或更改的材料的那些檔案。然後可以使用Regex來刪除過時的材料,最後,可以再次使用Regex來尋找並替換那些需要替換的標記。

另一個說明Regex非常有用的樣本是一種其字串處理能力還不為人所知的語言。VBScript 是 Visual Basic 的一個子集,具有豐富的字串處理功能。與 C 類似的 Visual Basic Scripting Edition 則沒有這一能力。Regex給 Visual Basic Scripting Edition 的字串處理能力帶來了明顯改善。不過,可能還是在 VBScript 中使用Regex的效率更高,它允許在單個運算式中執行多個字串操作

4.Regex文法
一個Regex就是由一般字元(例如字元 a 到 z)以及特殊字元(稱為元字元)組成的文字模式。該模式描述在尋找文字主體時待匹配的一個或多個字串。Regex作為一個模板,將某個字元模式與所搜尋的字串進行匹配。

這裡有一些可能會遇到的Regex樣本:

Visual BasicVBScript匹配
Scripting Edition

/^\[ \t]*$/chr(34)^\[ \t]*$chr(34)匹配一個空白行。

/\d{2}-\d{5}/chr(34)\d{2}-\d{5}chr(34)驗證一個ID號碼是否由一個2位字,一個連字號以及一個5位元字組成。

/<(.*)>.*<\/\1>/chr(34)<(.*)>.*<\/\1>chr(34)匹配一個 HTML 標籤。


下表是元字元及其在Regex上下文中的行為的一個完整列表:

字元描述

\將下一個字元標記為一個特殊字元、或一個原義字元、或一個 後向引用、或一個八進位轉義符。例如,'n' 匹配字元 chr(34)nchr(34)。'\n' 匹配一個分行符號。序列 '\\' 匹配 chr(34)\chr(34) 而 chr(34)\(chr(34) 則匹配 chr(34)(chr(34)。

^匹配輸入字串的開始位置。如果設定了 RegExp 對象的 Multiline 屬性,^ 也匹配 '\n' 或 '\r' 之後的位置。

$匹配輸入字串的結束位置。如果設定了 RegExp 對象的Multiline 屬性,$ 也匹配 '\n' 或 '\r' 之前的位置。

*匹配前面的子運算式零次或多次。例如,zo* 能匹配 chr(34)zchr(34) 以及chr(34)zoochr(34)。 * 等價於{0,}。

+匹配前面的子運算式一次或多次。例如,'zo+' 能匹配 chr(34)zochr(34) 以及 chr(34)zoochr(34),但不能匹配 chr(34)zchr(34)。+ 等價於 {1,}。

?匹配前面的子運算式零次或一次。例如,chr(34)do(es)?chr(34) 可以匹配chr(34)dochr(34) 或 chr(34)doeschr(34) 中的chr(34)dochr(34) 。? 等價於 {0,1}。

{n}n 是一個非負整數。匹配確定的 n 次。例如,'o{2}' 不能匹配chr(34)Bobchr(34) 中的 'o',但是能匹配 chr(34)foodchr(34) 中的兩個 o。

{n,}n 是一個非負整數。至少匹配n 次。例如,'o{2,}' 不能匹配 chr(34)Bobchr(34) 中的 'o',但能匹配 chr(34)fooooodchr(34) 中的所有 o。'o{1,}'
等價於 'o+'。'o{0,}' 則等價於 'o*'。

{n,m}m 和 n 均為非負整數,其中n <= m。最少匹配 n 次且最多匹配 m 次。劉, chr(34)o{1,3}chr(34) 將匹配 chr(34)foooooodchr(34) 中的前三個o。'o{0,1}'等價於'o?'。請注意在逗號和兩個數之間不能有空格

?當該字元緊跟在任何一個其他限制符 (*, +, ?, {n}, {n,},{n,m}) 後面時,匹配模式是非貪婪的。非貪婪模式儘可能少的匹配所搜尋的字串,而預設的貪婪模式則儘可能多的匹配所搜尋的字串。例如,對於字串 chr(34)oooochr(34),'o+?' 將匹配單個 chr(34)ochr(34),而 'o+' 將匹配所有 'o'。

.匹配除 chr(34)\nchr(34) 之外的任何單個字元。要匹配包括 '\n' 在內的任何字元,請使用象 '[.\n]' 的模式。

(pattern)匹配pattern 並擷取這一匹配。所擷取的匹配可以從產生的 Matches 集合得到,在VBScript 中使用 SubMatches 集合,在Visual Basic Scripting Edition 中則使用 $0…$9 屬性。要匹配圓括弧字元,請使用 '\(' 或 '\)'。

(?:pattern)匹配 pattern 但不擷取匹配結果,也就是說這是一個非擷取匹配,不進行儲存供以後使用。這在使用 chr(34)或chr(34) 字元 (|) 來組合一個模式的各個部分是很有用。例如, 'industr(?:y|ies) 就是一個比 'industry|industries' 更簡略的運算式。

(?=pattern)正向預查,在任何匹配 pattern 的字串開始處匹配尋找字串。這是一個非擷取匹配,也就是說,該匹配不需要擷取供以後使用。例如,'Windows (?=95|98|NT|2000)' 能匹配chr(34)Windows 2000chr(34)中的chr(34)Windowschr(34),但不能匹配chr(34)Windows3 .1chr(34)中chr(34)Windowschr(34)。預查不消耗字元,也就是說,在一個匹配發生後,在最後一次匹配之後立即開始下一次匹配的搜尋,而不是從包含預查的字元之後開始。

(?!pattern)負向預查,在任何不匹配Negative lookahead matches the search string at any point where a string not matching pattern 的字串開始處匹配尋找字串。這是一個非擷取匹
配,也就是說,該匹配不需要擷取供以後使用。例如'Windows(?!95|98|NT|2000)' 能匹配 chr(34)Windows 3.1chr(34) 中的 chr(34)Windowschr(34),
但不能匹配 chr(34)Windows 2000chr(34) 中的 chr(34)Windowschr(34)。預查不消耗字元,也就是說,在一個匹配發生後,在最後一次匹配之後立即開始下一次匹配的搜尋,而不是從包含預查的字元之後開始

x|y匹配 x 或 y。例如,'z|food' 能匹配 chr(34)zchr(34) 或 chr(34)foodchr(34)。'(z|f)
ood' 則匹配 chr(34)zoodchr(34) 或 chr(34)foodchr(34)。

[xyz]字元集合。匹配所包含的任意一個字元。例如, '[abc]' 可以匹配 chr(34)plainchr(34) 中的 'a'。

[^xyz]負值字元集合。匹配未包含的任一字元。例如, '[^abc]' 可以匹配 chr(34)plainchr(34) 中的'p'。

[a-z]字元範圍。匹配指定範圍內的任一字元。例如,'[a-z]' 可以匹配 'a' 到 'z' 範圍內的任意小寫字母字元。

[^a-z]負值字元範圍。匹配任何不在指定範圍內的任一字元。例如, '[^a-z]' 可以匹配任何不在 'a' 到 'z' 範圍內的任一字元。

\b匹配一個單詞邊界,也就是指單詞和空格間的位置。例如, 'er\b' 可以匹配chr(34)neverchr(34) 中的 'er',但不能匹配 chr(34)verbchr(34) 中的 'er'。

\B匹配非單詞邊界。'er\B' 能匹配 chr(34)verbchr(34) 中的 'er',但不能匹配 chr(34)neverchr(34) 中的 'er'。

\cx匹配由x指明的控制字元。例如, \cM 匹配一個 Control-M 或斷行符號符。 x 的值必須為 A-Z 或 a-z 之一。否則,將 c 視為一個原義的 'c' 字元。

\d匹配一個數字字元。等價於 [0-9]。

\D匹配一個非數字字元。等價於 [^0-9]。

\f匹配一個換頁符。等價於 \x0c 和 \cL。

\n匹配一個分行符號。等價於 \x0a 和 \cJ。

\r匹配一個斷行符號符。等價於 \x0d 和 \cM。

\s匹配任何空白字元,包括空格、定位字元、換頁符等等。等價於 [ \f\n\r\t\v]。

\S匹配任何非空白字元。等價於 [^ \f\n\r\t\v]。

\t匹配一個定位字元。等價於 \x09 和 \cI。

\v匹配一個垂直定位字元。等價於 \x0b 和 \cK。

\w匹配包括底線的任何單詞字元。等價於'[A-Za-z0-9_]'。

\W匹配任何非單詞字元。等價於 '[^A-Za-z0-9_]'。

\xn匹配 n,其中 n 為十六進位轉義值。十六進位轉義值必須為確定的兩個數字長。例如, '\x41' 匹配 chr(34)Achr(34)。'\x041' 則等價於 '\x04' & chr(34)1chr(34)。Regex中可以使用 ASCII 編碼。.

\num匹配 num,其中num是一個正整數。對所擷取的匹配的引用。例如,'(.)\1' 匹配兩個連續的相同字元。

\n標識一個八進位轉義值或一個後向引用。如果 \n 之前至少 n 個擷取的子運算式,則 n 為後向引用。否則,如果 n 為八位元字 (0-7),則 n 為一個八進位轉義值。

\nm標識一個八進位轉義值或一個後向引用。如果 \nm 之前至少有is preceded by at least nm 個擷取得子運算式,則 nm 為後向引用。如果 \nm 之前至少有 n 個擷取,則 n 為一個後跟文字 m 的後向引用。如果前面的條件都不滿足,若n 和 m 均為八位元字 (0-7),則 \nm 將匹配八進位轉義值 nm。

\nml如果 n 為八位元字 (0-3),且 m 和 l 均為八位元字 (0-7),則匹配八進位轉義值 nml。

\un匹配 n,其中 n 是一個用四個十六進位數字表示的Unicode字元。例如, \u00A9 匹配著作權符號 (?)。

5.建立Regex

構造Regex的方法和建立數學運算式的方法一樣。也就是用多種元字元與操作符將小的運算式結合在一起來建立更大的運算式。

可以通過在一對分隔字元之間放入運算式模式的各種組件來構造一個Regex。對 Visual Basic Scripting Edition 而言,分隔字元為一對正斜杠 (/) 字元。例如:

/expression/

對 VBScript 而言,則採用一對引號 (chr(34)chr(34)) 來確定Regex的邊界。例如:

chr(34)expressionchr(34)

在上面所示的兩個樣本中,Regex模式 (expression) 均儲存在RegExp 對象的Pattern 屬性中。

<<------------------------------------------------------>>

6.優先權順序
在構造Regex之後,就可以象數學運算式一樣來求值,也就是說,可以從左至右並按照一個優先權順序來求值。

下表從最高優先順序到最低優先順序列出各種Regex操作符的優先權順序:

操作符描述

\轉義符

(), (?:), (?=), []圓括弧和方括弧

*, +, ?, {n}, {n,}, {n,m}限定符

^, $, \anymetacharacter位置和順序

|“或”操作

<<---------------------------------------------------------->>

7.一般字元
一般字元由所有那些未顯式指定為元字元的列印和非列印字元組成。這包括所有的大寫和小寫字母字元,所有數字,所有標點符號以及一些符號。

最簡單的Regex是一個單獨的一般字元,可以匹配所搜尋字串中的該字元本身。例如,單字元模式 'A' 可以匹配所搜尋字串中任何位置出現的字母 'A'。這裡有一些單字元Regex模式的樣本:

/a/
/7/
/M/

等價的 VBScript 單字元Regex為:

chr(34)achr(34)
chr(34)7chr(34)
chr(34)Mchr(34)

可以將多個單字元組合在一起得到一個較大的運算式。例如,下面的 Visual Basic Scripting Edition Regex不是別的,就是通過組合單字元運算式 'a'、'7'以及 'M' 所建立出來的一個運算式。

/a7M/

等價的 VBScript 運算式為:

chr(34)a7Mchr(34)

請注意這裡沒有串連操作符。所需要做的就是將一個字元放在了另一個字元後面。

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

8.特殊字元

有不少元字元在試圖對其進行匹配時需要進行特殊的處理。要匹配這些特殊字元,必須首先將這些字元轉義,也就是在前面使用一個反斜線 (\)。下表給出了這些特殊字元及其含義:

特殊字元說明

$匹配輸入字串的結尾位置。如果設定了 RegExp 對象的 Multiline屬性,則 $ 也匹配 '\n' 或 '\r'。要匹配 $ 字元本身,請使用 \$。

( )標記一個子運算式的開始和結束位置。子運算式可以擷取供以後使用。要匹配這些字元,請使用 \( 和 \)。

*匹配前面的子運算式零次或多次。要匹配 * 字元,請使用 \*。

+匹配前面的子運算式一次或多次。要匹配 + 字元,請使用 \+。

.匹配除分行符號 \n之外的任何單字元。要匹配 .,請使用 \。

標記一個中括號運算式的開始。要匹配 [,請使用 \[。

?匹配前面的子運算式零次或一次,或指明一個非貪婪限定符。要匹配 ? 字元,請使用 \?。

\將下一個字元標記為或特殊字元、或原義字元、或後向引用、或八進位轉義符。例如, 'n' 匹配字元 'n'。'\n' 匹配分行符號。序列 '\\' 匹配 chr(34)\chr(34),而 '\(' 則匹配 chr(34)(chr(34)。

^匹配輸入字串的開始位置,除非在方括號運算式中使用,此時它表示不接受該字元集合。要匹配 ^ 字元本身,請使用 \^。

{標記限定符運算式的開始。要匹配 {,請使用 \{。

|指明兩項之間的一個選擇。要匹配 |,請使用 \|。


9.非列印字元

有不少很有用的非列印字元,偶爾必須使用。下表顯示了用來表示這些非列印字元的逸出序列:

字元含義

\cx匹配由x指明的控制字元。例如, \cM 匹配一個 Control-M 或斷行符號符。
x 的值必須為 A-Z 或 a-z 之一。否則,將 c 視為一個原義的 'c' 字
符。

\f匹配一個換頁符。等價於 \x0c 和 \cL。

\n匹配一個分行符號。等價於 \x0a 和 \cJ。

\r匹配一個斷行符號符。等價於 \x0d 和 \cM。

\s匹配任何空白字元,包括空格、定位字元、換頁符等等。等價於
[\f\n\r\t\v]。

\S匹配任何非空白字元。等價於 [^ \f\n\r\t\v]。

\t匹配一個定位字元。等價於 \x09 和 \cI。

\v匹配一個垂直定位字元。等價於 \x0b 和 \cK。

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

10.字元匹配

句點 (.) 匹配一個字串中任何單個的列印或非列印字元,除了分行符號 (\n) 之外。下面的 Visual Basic Scripting Edition Regex可以匹配 'aac'、'abc'、'acc'、'adc'如此等等,同樣也可以匹配 'a1c'、'a2c'、a-c'以及 a#c': /a.c/

等價的 VBScript Regex為:

chr(34)a.cchr(34)

如果試圖匹配一個包含檔案名稱的字串,其中句點 (.) 是輸入字串的一部分,則可以在Regex中的句點前面加上一個反斜線 (\) 字元來實現這一要求。舉例來說,下面的 Visual Basic Scripting Edition Regex就能匹配 'filename.ext':/filename\.ext/

對 VBScript 而言,等價的運算式如下所示:

chr(34)filename\.extchr(34)

這些運算式仍然是相當有限的。它們只允許匹配任何單字元。很多情況下,對從列表中匹配特殊字元十分有用。例如,如果輸入文字中包含用數字表示為Chapter 1, Chapter 2諸如此類的章區段標頭,你可能需要找到這些章區段標頭。


括號運算式

可以在一個方括弧 ([ 和 ]) 中放入一個或多個單字元,來建立一個待匹配的列表。如果字元被放入括弧中括起來,則該列表稱為括號運算式。括弧內和其他任何地方一樣,一般字元代表其本身,也就是說,它們匹配輸入文字中出現的一處自己。大多數特殊字元在位於括號運算式中時都將失去其含義。這裡有一些例外:

1.']' 字元如果不是第一項,則將結束一個列表。要在列表中匹配 ']' 字元,請將其放在第一項,緊跟在開始的 '[' 後面。

2.'\' 仍然作為轉義符。要匹配 '\' 字元,請使用 '\\'。

括號運算式中所包含的字元只匹配該括號運算式在Regex中所處位置的一個單字元。下面的 Visual Basic Scripting Edition Regex可以匹配 'Chapter 1'、'Chapter 2'、'Chapter 3'、'Chapter 4' 以及 'Chapter 5':

/Chapter ][12345]/

在 VBScript 中要匹配同樣的章區段標頭,請使用下面的運算式:

chr(34)Chapter [12345]chr(34)

請注意單詞 'Chapter' 及後面的空格與括弧內的字元的位置關係是固定的。因此,括號運算式只用來指定滿足緊跟在單詞 'Chapter' 和一個空格之後的單字元位置的字元集合。這裡是第九個字元位置。

如果希望使用範圍而不是字元本身來表示待匹配的字元,則可以使用連字號將該範圍的開始和結束字元分開。每個字元的字元值將決定其在一個範圍內的相對順序。下面的 Visual Basic Scripting Edition Regex包含了一個等價於上面所示的括弧列表的範圍運算式。

/Chapter [1-5]/

VBScipt 中相同功能的運算式如下所示:

chr(34)Chapter [1-5]chr(34)

如果以這種方式指定範圍,則開始和結束值都包括在該範圍內。有一點特別需要注意的是,在 Unicode 排序中起始值一定要在結束值之前。



相關文章

Cloud Intelligence Leading the Digital Future

Alibaba Cloud ACtivate Online Conference, Nov. 20th & 21st, 2019 (UTC+08)

Register Now >

11.11 Big Sale for Cloud

Get Unbeatable Offers with up to 90% Off,Oct.24-Nov.13 (UTC+8)

Get It Now >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。