在一年級(jí)時(shí),我們比較輕松的了解了
Java & regex (是正則表達(dá)式的縮寫,與Java的包無(wú)關(guān))的一些基本用法。一年級(jí)的主要任務(wù)是:① 搞了幾個(gè)可運(yùn)行的程序。后面要學(xué)習(xí)的東西,我們可以用相似的程序處理。
② 我們找到了與regex相關(guān)的Java類——Pattern和Matcher、String、StringBuffer和StringTokenizer后面我們著重學(xué)習(xí)它們。
(另外,暫時(shí)不想去搞的幾個(gè)咚咚——PatternSyntaxException、java.util.Scanner)。)。
③ 我們了解了regex的大致特點(diǎn),一種生成字符串的字符串。不管它將會(huì)如何復(fù)雜,也不過是一個(gè)特殊的字符串,而已。
到了二年級(jí),我們準(zhǔn)備系統(tǒng)的學(xué)習(xí),因而感到凝重起來(lái)。yqj2065發(fā)現(xiàn)了一個(gè)超好的工具——Regulator,它是一個(gè)高級(jí)的、free regex的測(cè)試和學(xué)習(xí)工具,它讓你……到這里http://regex.osherove.com/自己看,我去下載了,呵呵。
安裝……問題?它需要一個(gè)什么.Net Framework!??!一個(gè)小小的工具要那個(gè)大大的Framework干嘛,偏偏前幾天我重裝了系統(tǒng),暈。心中又對(duì)M$反感起來(lái)?!咎峁┝似?/span>C#源代碼?!?/span>
我又發(fā)現(xiàn)了一個(gè)超好的工具——EditPad Pro,它是一個(gè)高級(jí)的、free regex的測(cè)試和學(xué)習(xí)工具,它讓你……到這里Download EditPad Pro Demo for Windows 95/98/ME/NT4/2000/XP (1.8 MB)自己看,我去下載了,呵呵。
問題是,它的 regex flavor is almost identical to the one used in Perl 5。這使我有點(diǎn)不放心,因?yàn)?/span>Java在其Pattern文檔中比較了與Perl 5的異同。
本來(lái)想系統(tǒng)學(xué)學(xué)Java& regex,可心中打著小鼓,情不自禁地臉黑黑了?!?/span>yqj2065提示:我想學(xué)習(xí)的與你想學(xué)習(xí)的可能不同。跳過你不喜歡的部分。】
全部2年級(jí)的主題: 正則表達(dá)式語(yǔ)法
通過一年級(jí)學(xué)習(xí),我發(fā)現(xiàn),兩條腿走路很不爽,一下抬起Java,一下提起regex,我想一條腿走路。我蹦我蹦我蹦蹦,像三級(jí)跳遠(yuǎn)一樣,專注于regex的學(xué)習(xí)。我們不要JVM,可能輕松了許多。
regular expression翻譯成正則表達(dá)式,一看就是很有學(xué)問的樣子。如果我說正則表達(dá)式起始于Java,沒有人相信;如果有人說正則表達(dá)式起始于UNIX系統(tǒng),我們也不要相信。
1956 年, 數(shù)學(xué)家Stephen Kleene在Warren McCulloch and Walter Pitts早期神經(jīng)系統(tǒng)工作的基礎(chǔ)上,搞成了一個(gè)數(shù)學(xué)符號(hào)體系——regular sets,規(guī)則的集合。這個(gè)咚咚很快被計(jì)算機(jī)科學(xué)家用于編譯器的掃描或詞法分析( lexical analysis)中。因此,正則表達(dá)式起始于自動(dòng)機(jī)理論和形式語(yǔ)言理論(我們會(huì)在形式語(yǔ)言與自動(dòng)機(jī)理論課程中接觸正則表達(dá)式,屬于理論計(jì)算機(jī)科學(xué)),我們?cè)?/span>編譯原理課程中,也可能會(huì)接觸到正則表達(dá)式?!?/span>ref:《編譯原理及實(shí)踐》】
正則表達(dá)式強(qiáng)大的文本處理能力,很快被Kenneth Thompson應(yīng)用到Unix的工具軟件grep中;此后,正則表達(dá)式被廣泛應(yīng)用于Unix系操作系統(tǒng),Perl、PHP,Delphi、JavaScript、C#(.NET),Java、Python、Ruby等語(yǔ)言和開發(fā)環(huán)境,以及很多的應(yīng)用軟件特別是文本編輯器中。值得一提的是,Perl regular expressions形成了一種大致的標(biāo)準(zhǔn),人們常常使用pcre (Perl Compatible Regular Expressions),如同IBM兼容機(jī)。【http://en.wikipedia.org/wiki】yqj2065
為什么Java直到JDK1.4才提供對(duì)regex的支持呢?這讓很多人不滿。在JDK1.4出現(xiàn)之前,有一些第三方庫(kù)出現(xiàn),現(xiàn)在可能不需要它了。例如:
l Package com.stevesoft.pat【http://www.javaregex.com/patfull.html】,這里有一些有趣的東西還可以看看。比如ReGame, the regular expression game。
l
自從XML為人們熟悉以來(lái),定義語(yǔ)言的語(yǔ)言就不神秘了。直觀地說,regex是生成字符串的字符串。這些由一個(gè)regex生成的字符串組成了一種語(yǔ)言。
正則表達(dá)式r完全由它所匹配的字符串集合(串集)來(lái)定義。這個(gè)集合稱為由正則表達(dá)式生成的語(yǔ)言(language generated by the regular expression),可以寫作L(r)——以r為模式的L。此處的語(yǔ)言只表示“串的集合”。如:
L(a)={a}
L(a+)={a,aa,aaa,aaaa,……}
該語(yǔ)言首先依賴于適用的字符集,一般是ASCII字符的集合或它的某個(gè)子集,Java則使用Unicode字符集,這個(gè)字符集是我們?cè)谡齽t表達(dá)式中能使用的字母表——∑。
正則表達(dá)式r的組成:
l 字母表中的字符。要注意,此時(shí)L(a+)中的a不是簡(jiǎn)單的a,它是一個(gè)模式(模板)。
l 有特殊含義的字符——元字符(meta-character)。它們可能也是字母表中正規(guī)字符,如* +等等,也可能不是字母表中字符,如\n,\x09等等。這時(shí),我們通過轉(zhuǎn)義字符(escape character)來(lái)處理。源代碼中,對(duì)于前者,加一個(gè)\;對(duì)于后者,去掉\。
【下面的符號(hào)指集合的運(yùn)算】
最小正則表達(dá)式有三種形式:
l L (a) = {a}。單一字符a。此時(shí)a可能是任何一個(gè)合法的字母表中的字符。如L (x) = {x}。
l L(ε) = {ε}。ε(epsilon)表示空串(empty string)——空串就是不包含任何字符的串。類似String str=””.
l L(Ф)= { }.Ф表示空集(empty set),該語(yǔ)言與任何串都不匹配。
注意{ε}和{ }的區(qū)別:{ }集不包括任何串,而{ }則包含一個(gè)串——沒有任何字符的串。
正則表達(dá)式的三種基本運(yùn)算:
l 并集——用元字符|(豎線)表示。
如果r 和s 是正則表達(dá)式,那么正則表達(dá)式r | s 可匹配被r 或s 匹配的任意串。r | s 語(yǔ)言是r 語(yǔ)言和s 語(yǔ)言的聯(lián)合(union)。
例如:L (a)={a}, L (c)={ c }則
L (a|c)= L (a)∪L (c)= {a}∪{ c }={a,c}.
又如:L (a|b|c|d) = { a, b, c, d}。
【并集在Java的正則表達(dá)式中,書寫方式有:a|c、[ac] 、a-z 、等等】
l 連結(jié)——不用元字符,順著寫就行了。
正則表達(dá)式r 和正則表達(dá)式s 的連結(jié)可寫作rs。
這里說明一下括號(hào)()元字符的作用。正則表達(dá)式L (a b)={a b},L (c)={c},那么正則表達(dá)式L((a|b)c)= L (a|b)⊙ L(c)={ac,bc}
【連結(jié)書寫方式有:a{2,4}等等】
r 是一個(gè)正則表達(dá)式。正則表達(dá)式r * 將匹配r串的任意有窮連結(jié)。雖然我們說L(a*)={ }∪{ a}∪{aa}∪{aaa}∪……={ε,a,aa,aaa,aaaa,……}是一個(gè)無(wú)窮集。
【閉包在Java的正則表達(dá)式中派生了一些書寫方式:
L(a+)=L(a*)-ε即a+匹配a,aa,aaa,aaaa,……
L(a?) = L (ε|a). 即a? 匹配ε、a?!?o:p>
運(yùn)算的優(yōu)先和括號(hào)的使用
三種基本運(yùn)算的優(yōu)先級(jí)為閉包>連結(jié)>并集,除非使用()改變。
L(a|b*)={ a,ε,b, bb, bbb…… }
L((a|b)*) = {ε, a, b, aa, ab, ba, bb, …… },
定義正則表達(dá)式(regular expression)是以下的一種:
1. 基本(b a s i c)正則表達(dá)式由一個(gè)單字符a(其中a 在正規(guī)字符的字母表å中),以及元字符或元字符組成。在第1種情況下,L (a) = {a};在第2種情況下,L (ε) ={ε};在第3種情況下,L (Ф) = {}。
r和s 均是正則表達(dá)式時(shí):
2. r | s 格式的表達(dá)式: L (r | s) = L (r) ∪ L (s)。
3. rs 格式的表達(dá)式: L (r s) = L (r) L (s)。
4. r* 格式的表達(dá)式: L (r*) = L (r) *。
5. (r)格式的表達(dá)式: L ( (r)) = L (r),括號(hào)并不改變語(yǔ)言,它們只調(diào)整運(yùn)算的優(yōu)先權(quán)。
【這些東西,都是應(yīng)該知道的基本知識(shí)哦。ref:《編譯原理及實(shí)踐》】
練習(xí)
2.1-1 在簡(jiǎn)單字母表∑ = {a, b, c}上構(gòu)造一種語(yǔ)言,它是僅包括一個(gè)b 的所有串的集合:如aaba、abcca等等。
答案: (a|c)*b(a|c)*
例如:String str=“abaaabcccbabaaaaabc”,匹配時(shí)替換為Java。則輸出為:JavaJavaJavaJavaJava。為什么上面的匹配方式不是abaaabcccbabaaaaabc,因?yàn)榇嬖谒^的最大匹配——貪婪匹配。
2.1-2 在字母表∑ ={a, b}上構(gòu)造一種語(yǔ)言,串S的集合是由一個(gè)b及在其前后有相同數(shù)目的a 組成:S = { b, aba, aabaa, aaabaaa, . . . }
答案:搞不定。正則表達(dá)式并不能描述這個(gè)集合。重復(fù)運(yùn)算只有閉包運(yùn)算*一種,但a*ba*能保證b 前后的a 的數(shù)量是否相等。它通常表示為“不能計(jì)算的正則表達(dá)式”——在自動(dòng)機(jī)理論中的數(shù)學(xué)論證是著名的Pumping lemma定理。
聯(lián)系客服