正則表達式(REs)通常被錯誤地認為是只有少數(shù)人理解的一種神秘語言。在表面上它們確實看起來雜亂無章,如果你不知道它的語法,那么它的代碼在你眼里只是一堆文字垃圾而已。實際上,正則表達式是非常簡單并且可以被理解。讀完這篇文章后,你將會通曉正則表達式的通用語法。 支持多種平臺 正則表達式最早是由數(shù)學家Stephen Kleene于1956年提出,他是在對自然語言的遞增研究成果的基礎上提出來的。具有完整語法的正則表達式使用在字符的格式匹配方面上,后來被應用到熔融信息技術領域。自從那時起,正則表達式經(jīng)過幾個時期的發(fā)展,現(xiàn)在的標準已經(jīng)被ISO(國際標準組織)批準和被Open Group組織認定。 正則表達式并非一門專用語言,但它可用于在一個文件或字符里查找和替代文本的一種標準。它具有兩種標準:基本的正則表達式(BRE),擴展的正則表達式(ERE)。ERE包括BRE功能和另外其它的概念。 許多程序中都使用了正則表達式,包括xsh,egrep,sed,vi以及在UNIX平臺下的程序。它們可以被很多語言采納,如HTML 和XML,這些采納通常只是整個標準的一個子集。 比你想象的還要普通隨著正則表達式移植到交叉平臺的程序語言的發(fā)展,這的功能也日益完整,使用也逐漸廣泛。網(wǎng)絡上的搜索引擎使用它,e-mail程序也使用它,即使你不是一個UNIX程序員,你也可以使用規(guī)則語言來簡化你的程序而縮短你的開發(fā)時間。 正則表達式101
很多正則表達式的語法看起來很相似,這是因為你以前你沒有研究過它們。通配符是RE的一個結構類型,即重復操作。讓我們先看一看ERE標準的最通用的基本語法類型。為了能夠提供具有特定用途的范例,我將使用幾個不同的程序。 字符匹配
正則表達式的關鍵之處在于確定你要搜索匹配的東西,如果沒有這一概念,Res將毫無用處。
|
Table B: Regular expression repetition operators |
|||
操作 |
解釋 |
例子 |
結果 |
? |
Match any character one time, if it exists |
egrep “?erd” sample.txt |
Will match “berd”, “herd”, etc. and “erd” |
* |
Match declared element multiple times, if it exists |
egrep “n.*rd” sample.txt |
Will match “nerd”, “nrd”, “neard”, etc. |
+ |
Match declared element one or more times |
egrep “[n]+erd” sample.txt |
Will match “nerd”, “nnerd”, etc., but not “erd” |
{n} |
Match declared element exactly n times |
egrep “[a-z]{2}erd” sample.txt |
Will match “cherd”, “blerd”, etc. but not “nerd”, “erd”, “buzzerd”, etc. |
{n,} |
Match declared element at least n times |
egrep “.{2,}erd” sample.txt |
Will match “cherd” and “buzzerd”, but not “nerd” |
{n,N} |
Match declared element at least n times, but not more than N times |
egrep “n[e]{1,2}rd” sample.txt |
Will match “nerd” and “neerd” |
錨是指它所要匹配的格式,如圖C所示。使用它能方便你查找通用字符的合并。例如,我用vi行編輯器命令:s來代表substitute,這一命令的基本語法是:
s/pattern_to_match/pattern_to_substitute/
?
Table C: Regular expression anchors |
|||
操作 |
解釋 |
例子 |
結果 |
^ |
Match at the beginning of a line |
s/^/blah / |
Inserts “blah “ at the beginning of the line |
$ |
Match at the end of a line |
s/$/ blah/ |
Inserts “ blah” at the end of the line |
\< |
Match at the beginning of a word |
s/\</blah/ |
Inserts “blah” at the beginning of the word |
|
|
egrep “\<blah” sample.txt |
Matches “blahfield”, etc. |
\> |
Match at the end of a word |
s/\>/blah/ |
Inserts “blah” at the end of the word |
|
|
egrep “\>blah” sample.txt |
Matches “soupblah”, etc. |
\b |
Match at the beginning or end of a word |
egrep “\bblah” sample.txt |
Matches “blahcake” and “countblah” |
\B |
Match in the middle of a word |
egrep “\Bblah” sample.txt |
Matches “sublahper”, etc. |
間隔
Res中的另一可便之處是間隔(或插入)符號。實際上,這一符號相當于一個OR語句并代表|符號。下面的語句返回文件sample.txt中的“nerd” 和 “merd”的句柄:
egrep “(n|m)erd” sample.txt
間隔功能非常強大,特別是當你尋找文件不同拼寫的時候,但你可以在下面的例子得到相同的結果:
egrep “[nm]erd” sample.txt
當你使用間隔功能與Res的高級特性連接在一起時,它的真正用處更能體現(xiàn)出來。
一些保留字符
Res的最后一個最重要特性是保留字符(也稱特定字符)。例如,如果你想要查找“ne*rd”和“ni*rd”的字符,格式匹配語句“n[ei]*rd”與“neeeeerd” 和 “nieieierd”相符合,但并不是你要查找的字符。因為‘*’(星號)是個保留字符,你必須用一個反斜線符號來替代它,即:“n[ei]\*rd”。其它的保留字符包括:
- ^ (carat)
- . (period)
- [ (left bracket}
- $ (dollar sign)
- ( (left parenthesis)
- ) (right parenthesis)
- | (pipe)
- * (asterisk)
- + (plus symbol)
- ? (question mark)
- { (left curly bracket, or left brace)
- \ backslash
一旦你把以上這些字符包括在你的字符搜索中,毫無疑問Res變得非常的難讀。比如說以下的PHP中的eregi搜索引擎代碼就很難讀了。
eregi("^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*$",$sendto)
你可以看到,程序的意圖很難把握。但如果你拋開保留字符,你常常會錯誤地理解代碼的意思。
總結
在本文中,我們揭開了正則表達式的神秘面紗,并列出了ERE標準的通用語法。如果你想閱覽Open Group組織的規(guī)則的完整描述,你可以參見: Regular Expressions ,歡迎你在其中的討論區(qū)發(fā)表你的問題或觀點。