1、何謂正則表達(dá)式正則表達(dá)式(regular expression)就是用一個“字符串”來描述一個特征,然后去驗(yàn)證另一個“字符串”是否符合這個特征,即一段字符串的模式。比如,表達(dá)式“ab+” 描述的特征是“一個 'a' 和 任意個 'b' ”,那么 'ab', 'abb', 'abbbbbbbbbb' 都符合這個特征。 正則表達(dá)式的功能非常強(qiáng)大,打個比方,比如在關(guān)系數(shù)據(jù)庫中,SQL語言的地位是顯赫的,功能是強(qiáng)大的,那么在字符串處理這個領(lǐng)域,正則表達(dá)式可以和SQL語言在關(guān)系數(shù)據(jù)庫中扮演的角色相媲美。從我本人從事多年的軟件開發(fā)實(shí)踐中可以感覺到,正則表達(dá)式是值得每一個從事計(jì)算機(jī)相關(guān)工作的人去學(xué)習(xí)、掌握,我們可以從中受惠。 正則表達(dá)式可以用來:(1)驗(yàn)證字符串是否符合指定特征,比如驗(yàn)證是否是合法的郵件地址。(2)用來查找字符串,從一個長的文本中查找符合指定特征的字符串,比查找固定字符串更加靈活方便。(3)用來替換,比普通的替換更強(qiáng)大。(4)split字符串。 正則表達(dá)式學(xué)習(xí)起來其實(shí)是很簡單的,不多的幾個較為抽象的概念也很容易理解。之所以很多人感覺正則表達(dá)式比較復(fù)雜,一方面是因?yàn)榇蠖鄶?shù)的文檔沒有做到由淺入深地講解,概念上沒有注意先后順序,給讀者的理解帶來困難;另一方面,各種引擎自帶的文檔一般都要介紹它特有的功能,然而這部分特有的功能并不是我們首先要理解的。 平時的開發(fā),常常在Java和.NET平臺下進(jìn)行,這兩個平臺都提供了相應(yīng)的正則表達(dá)式引擎,用起來感覺也很好。在VBA的開發(fā)中,盡管Excel中提供了很多的內(nèi)置函數(shù),幫助我們解決一些字符串處理相關(guān)的問題,但對有些情況,用內(nèi)置的函數(shù)或者編程來解決,常常會感覺到力不從心或者非常繁瑣,而用正則表達(dá)式來解決,卻變得非常簡單。所有我們在這里主要學(xué)習(xí)如何在VBA中使用正則表達(dá)式。 2、相關(guān)工具 工欲善其事,必先利其器,這是我們在使用正則表達(dá)式需要注意的地方,我們做任何事情,若善于利用一些有用的輔助工具,常常可以達(dá)到事半功倍的效果。那么在使用正則表達(dá)式的時候也是一樣,我們需要一些輔助工具來幫助我們更快、更好地完整任務(wù)。我在使用了多種正則表達(dá)式輔助開發(fā)工具后,經(jīng)過綜合地比較、評價(jià),最終鎖定的一款利器,堪比關(guān)羽手中的“青龍偃月刀”,所向披靡。
這款利器就是 RegexBuddy,相關(guān)介紹參見 www.,這是一款共享工具,功能上沒有限制,但只能用7天,要money的,需要注冊,不過大家在網(wǎng)上找regexbuddy 2.3.2 full version。 下面我們粗略地看一下RegexBuddy有哪些主要功能: 從上面的主要功能介紹我們可以看出,RegexBuddy絕對是我們處理正則表達(dá)式的不二選擇,是一款出色的正則表達(dá)式伴侶式工具,鄭重推薦大家使用。 3、正則表達(dá)式規(guī)則------字符 3.1 普通字符
字母、數(shù)字、漢字、下劃線、以及后邊章節(jié)中沒有特殊定義的標(biāo)點(diǎn)符號,都是"普通字符"。表達(dá)式中的普通字符,在匹配一個字符串的時候,匹配與之相同的一個字符。 舉例1:表達(dá)式 "c",在匹配字符串 "abcde" 時,匹配結(jié)果是:成功;匹配到的內(nèi)容是:"c";匹配到的位置是:開始于2,結(jié)束于3。(注:下標(biāo)從0開始還是從1開始,因當(dāng)前編程語言的不同而可能不同) 舉例2:表達(dá)式 "bcd",在匹配字符串 "abcde" 時,匹配結(jié)果是:成功;匹配到的內(nèi)容是:"bcd";匹配到的位置是:開始于1,結(jié)束于4。 3.2 特殊字符 3.3 不能顯示的字符 4、正則表達(dá)式引擎的內(nèi)部工作機(jī)制了解正則表達(dá)式引擎的內(nèi)部工作機(jī)制將有助于你更好地駕馭正則表達(dá)式,高效、簡潔書寫合理的正則表達(dá)式來完成任務(wù)。
有兩種類型的引擎:文本導(dǎo)向(text-directed)引擎和正則導(dǎo)向(regex-directed)引擎。Jeffrey Friedl把它們稱作DFA和NFA引擎。本文談到的是正則導(dǎo)向引擎。因?yàn)橐恍┓浅S杏玫奶匦裕纭岸栊浴绷吭~(lazy quantifiers)和反向引用(backreferences),只能在正則導(dǎo)向的引擎中實(shí)現(xiàn), 毫不意外這種引擎是目前最流行的引擎。 你可以輕易分辨所使用的引擎是哪一種,若反向引用或“惰性”量詞被實(shí)現(xiàn),則可以肯定你使用的是正則導(dǎo)向引擎。你可以作如下測試:將正則表達(dá)式<<regex|regex not>>應(yīng)用到字符串“regex not”。如果匹配的結(jié)果是regex,則是正則導(dǎo)向引擎。如果結(jié)果是regex not,則是文本導(dǎo)向引擎。 正則導(dǎo)向的引擎總是返回最左邊的匹配 這是非中重要的一點(diǎn):即使在后邊可能發(fā)現(xiàn)一個“更好”的匹配,正則導(dǎo)向的引擎也總是返回最左邊的匹配。 當(dāng)把<<cat>>應(yīng)用到“He captured a catfish for his cat”,引擎先比較<<c>>和“H”,結(jié)果失敗了。于是引擎再比較<<c>>和“e”,也失敗了。直到第四個字符,<<c>>匹配了“c”。<<a>>匹配了第五個字符。到第六個字符<<t>>沒能匹配“p”,也失敗了。引擎再繼續(xù)從第五個字符重新檢查匹配性。直到第十五個字符開始,<<cat>>匹配上了“catfish”中的“cat”,正則表達(dá)式引擎急切的返回第一個匹配的結(jié)果,而不會再繼續(xù)查找是否有其他更好的匹配。 5、字符類或者字符集 字符類(也稱為字符集)是由一對方括號“[]”括起來的字符集合。使用字符集,正則引擎可以只匹配多個字符中的一個。如果你想匹配一個“a”或一個“e”,使用<<[ae]>>。使用<<gr[ae]y>>匹配gray或grey。在你不確定你要搜索的字符是采用美國英語還是英國英語時特別有用。一個字符集只匹配一個字符,<<gr[ae]y>>將不會匹配graay或graey。字符集中的字符順序無關(guān)。
可以使用連字符“-”定義一個字符范圍作為字符集。<<[0-9]>>匹配0到9之間的單個數(shù)字??梢允褂貌恢挂粋€范圍。<<[0-9a-fA-F] >>匹配單個的十六進(jìn)制數(shù)字,并且大小寫不敏感。也可以結(jié)合范圍定義與單個字符定義。<<[0-9a-fxA-FX]>>匹配一個十六進(jìn)制數(shù)字或字母X。再次強(qiáng)調(diào)一下,字符和范圍定義的先后順序?qū)Y(jié)果沒有影響。 字符集的一些應(yīng)用 查找一個可能寫錯的單詞,比如<<sep[ae]r[ae]te>> 或 <<li[cs]en[cs]e>>。 反字符集 在左方括號“[”后面緊跟一個尖括號“^”,將會對字符集取反。結(jié)果是字符集將匹配任何不在方括號中的字符。不像“.”,取反字符集是可以匹配回車換行符的。 需要記住的很重要的一點(diǎn)是,取反字符集必須要匹配一個字符。<<q[^u]>>并不意味著:匹配一個q,后面沒有u跟著。它意味著:匹配一個q,后面跟著一個不是u的字符。所以它不會匹配“Iraq”中的q,而會匹配“Iraq is a country”中的q和一個空格符。事實(shí)上,空格符是匹配中的一部分,因?yàn)樗且粋€“不是u的字符”。 如果只想匹配一個q,條件是q后面有一個不是u的字符,可以用后面將講到的向前查看來解決。 字符集中的元字符 在字符集定義中為了將反斜杠“\”作為一個文字字符而非特殊含義的字符,你需要用另一個反斜杠對它進(jìn)行轉(zhuǎn)義。<<[\\x]>>將會匹配一個反斜杠和一個X?!癩^-”都可以用反斜杠進(jìn)行轉(zhuǎn)義,或者將他們放在一個不可能使用到他們特殊含義的位置。我們推薦后者,因?yàn)檫@樣可以增加可讀性。比如對于字符“^”,將它放在除了左括號“[”后面的位置,使用的都是文字字符含義而非取反含義。如<<[x^]>>會匹配一個x或^。<<[]x]>>會匹配一個“]”或“x”。<<[-x]>>或<<[x-]>>都會匹配一個“-”或“x”。 字符集的簡寫 字符集的重復(fù) 如果用“?*+”操作符來重復(fù)一個字符集,將會重復(fù)整個字符集。而不僅是它匹配的那個字符。正則表達(dá)式<<[0-9]+>>會匹配837以及222。 6、點(diǎn)號"." 使用“.”匹配幾乎任意字符
在正則表達(dá)式中,“.”是最常用的元字符之一。不幸的是,它也容易被誤用。 “.”匹配一個單個的字符而不管該字符是什么。唯一的例外是換行符。在本教程中談到的引擎,缺省情況下都是不匹配換行符的。因此在缺省情況下,“.”等價(jià)于字符集[^\n\r](Window)或[^\n]( Unix)。 這個例外是有歷史原因的,因?yàn)樵缙谑褂谜齽t表達(dá)式的工具是基于行的,它們都是一行一行的讀入一個文件,將正則表達(dá)式分別應(yīng)用到每一行上去,在這些工具中,字符串是不包含換行符的。因此“.”也就從不匹配換行符。 現(xiàn)代的工具和語言能夠?qū)⒄齽t表達(dá)式應(yīng)用到很大的字符串甚至整個文件上去。在Perl中,“.”可以匹配換行符的模式被稱作“單行模式”。很不幸,這是一個很容易混淆的名詞。因?yàn)檫€有所謂“多行模式”。多行模式只影響行首行尾的錨定(anchor),而單行模式只影響“.”。 其他語言和正則表達(dá)式庫也采用了Perl的術(shù)語定義。當(dāng)在.NET Framework中使用正則表達(dá)式類時,你可以用類似下面的語句來激活單行模式:Regex.Match(“string”,”regex”,RegexOptions.SingleLine) 保守地使用點(diǎn)號“.” 點(diǎn)號可以說是最強(qiáng)大的元字符。它允許你偷懶:用一個點(diǎn)號,就能匹配幾乎所有的字符。但是問題在于,它也常常會匹配不該匹配的字符。 以一個簡單的例子來說明。如何匹配一個具有“mm/dd/yy”格式的日期,想允許用戶來選擇分隔符。很快能想到的一個方案是<<\d\d.\d\d.\d\d>>??瓷先ニ芷ヅ淙掌凇?2/12/03”。問題在于02512703也會被認(rèn)為是一個有效的日期。 7、錨(anchor) 字符串開始和結(jié)束錨(anchor)
錨是一個特別的符號,它不匹配任何字符。相反,他們匹配的是字符之前或之后的位置?!癪”匹配一行字符串第一個字符前的位置。<<^a>>將會匹配字符串“abc”中的a。<<^b>>將不會匹配“abc”中的任何字符。 類似的,$匹配字符串中最后一個字符后面的位置。所以<<c$>>匹配“abc”中的c。 應(yīng)用場合 使用“^”和“$”作為行的開始和結(jié)束錨 如果有一個多行的字符串。例如:“first line\r\nsecond line”(其中\(zhòng)r\n表示一個換行符)。常常需要逐行處理而不是處理整個字符串。因此,幾乎所有的正則表達(dá)式引擎都提供一個選項(xiàng),可以擴(kuò)展這兩種錨的含義。“^”可以匹配字串的開始位置(在f之前),以及每一個換行符的后面位置(在\r\n和s之間)。類似的,$會匹配字串的結(jié)束位置(最后一個e之后),以及每個新行符的前面(在e與\r\n之間)。 在.NET中,當(dāng)你使用如下代碼時,將會定義錨匹配每一個換行符的前面和后面位置:Regex.Match("string", "regex", RegexOptions.Multiline) ;string str = Regex.Replace(Original, "^", "> ", RegexOptions.Multiline)--將會在每行的行首插入“> ”。 字符串絕對開始和結(jié)束錨(anchor) 8、 詞界 元字符<<\b>>也是一種類似于<<^>>和<<$>>的“錨”,用來匹配單詞邊界位置,匹配長度0。
有4種不同位置常被鑒定為“單詞邊界”:
“單詞字符”是可以用<<\w>>匹配的字符,“非單詞字符”是可以用<<\W>>匹配的字符。在大多數(shù)的正則表達(dá)式實(shí)現(xiàn)中,“單詞字符”通常包括<<[a-zA-Z0-9_]>>。 例如:<<\b4\b>>能夠匹配單個的4而不會匹配“44”中的4。可以說<<\b>>匹配一個“字母數(shù)字序列”的開始和結(jié)束的位置。 “單詞邊界”的反集為<<\B>>,他要匹配的位置是兩個“單詞字符”之間或者兩個“非單詞字符”之間的位置。
9、選擇符 可以使用選擇符<<|>>來匹配幾個正則表達(dá)式中的一個。
如果要查找文本串“cat”或者“dog”,可以用<<cat|dog>>。如果想有更多的選擇,只要擴(kuò)展列表<<cat|dog|mouse|fish>>。 選擇符在正則表達(dá)式中具有最低的優(yōu)先級,也就是說,它告訴引擎要么匹配選擇符左邊的所有表達(dá)式,要么匹配右邊的所有表達(dá)式??梢杂脠A括號來限制選擇符的作用范圍。如<<\b(cat|dog)\b>>,這樣告訴正則引擎把(cat|dog)當(dāng)成一個正則表達(dá)式單位來處理。 注意正則引擎的“Eager”性 正則引擎找到一個有效的匹配時,會停止搜索。因此在一定條件下,選擇符兩邊的表達(dá)式的順序?qū)Y(jié)果會有影響。假設(shè)用正則表達(dá)式搜索一個編程語言的函數(shù)列表:Get,GetValue,Set或SetValue。一個明顯的解決方案是<<Get|GetValue|Set|SetValue>>。 當(dāng)搜索SetValue時的結(jié)果,因?yàn)?lt;<Get>>和<<GetValue>>都失敗了,而<<Set>>匹配成功。因?yàn)檎齽t導(dǎo)向的引擎的"Eager"性,所以它會返回第一個成功的匹配,就是“Set”,而不去繼續(xù)搜索是否有其他更好的匹配。和期望的相反,正則表達(dá)式并沒有匹配整個字符串。有幾種可能的解決辦法。一是考慮到正則引擎的“Eager”性,改變選項(xiàng)的順序,例如使用<<GetValue|Get|SetValue|Set>>,這樣可以優(yōu)先搜索最長的匹配。也可以把四個選項(xiàng)結(jié)合起來成兩個選項(xiàng):<<Get(Value)?|Set(Value)?>>。因?yàn)閱柼栔貜?fù)符是貪婪的,所以SetValue總會在Set之前被匹配。 10、正則表達(dá)式實(shí)戰(zhàn)訓(xùn)練1光說不練也不行,在講理論的時候得配合實(shí)戰(zhàn)訓(xùn)練,效果才會更好。下面給一個例子,用來學(xué)習(xí)基本的正則編程。
題目:要求取得字符串中的所有數(shù)字。 題目本身比較簡單,我們可以采用常規(guī)的做法,從字符串的第一個字符開始,循環(huán)逐個判斷每一個字符是數(shù)字還是非數(shù)字...... 但常規(guī)做法顯得比較麻煩,我們來看如何使用正則表達(dá)式來解決這個問題。 思路有二: 究竟那種方式更好,大家自己判斷一下就可以了,比較容易的。 11、問號的使用在正則表達(dá)式中,問號使它前面的符號變成可選項(xiàng)。如:<<colou?r>>可以匹配"colour"和"color"。
使用圓括號使一組字符成為可選項(xiàng),問號在圓括號后。如:<<Nov(ember)?>>會匹配"Nov"和"November"。 在一個正則表達(dá)式中,可以使用多個問號,使多個符號成為可選項(xiàng)。如:<<Feb(ruary)? 23(rd)?>>匹配"February 23rd","February 23","Feb 23rd"和"Feb 23"。 在這里,要介紹正則表達(dá)式中的一個非常重要的概念------貪婪性。我們這里介紹的第一個貪婪的元字符就是問號。問號讓正則引擎有兩種選擇:盡力去匹配問號前的部分;不匹配問號錢的部分。而正則引擎總是試圖去匹配問號前的部分,只有當(dāng)這樣的嘗試失敗后,才會忽略掉問號前的部分,所以說問號是一個貪婪的元字符。 若用正則式<<Feb 23(rd)?>>去匹配字符串"Today is Feb 23rd, 2003",得到的結(jié)果總是"Feb 23rd"而不是"Feb 23",就是因?yàn)閱柼柕呢澙沸浴?/P> 12、重復(fù)量詞 使用*和+進(jìn)行重復(fù)
11、中已經(jīng)介紹過一種重復(fù)操作符或者說量詞:問號?。它告訴正則引擎匹配前導(dǎo)字符0次或者1次,效果就是使它成為可選的。 正則式 <[A-Za-z][A-Za-z0-9]*> 匹配沒有屬性的HTML標(biāo)簽,,“<”以及“>”是文字符號。第一個字符集[A-Za-z]匹配一個字母,第二個字符集[A-Za-z0-9]匹配一個字母或數(shù)字,星號重復(fù)第二個字符集一次或多次。因?yàn)槲覀兪褂眯翘?,第二個字符集有0個匹配也是正確的,所以這個正則式可以匹配一個標(biāo)簽"<B>"。匹配字符串"<HTML>"時,第一個字符集匹配"H",星號將會導(dǎo)致第二個字符集重復(fù)匹配三次,匹配到"TML"。 有限重復(fù) 許多現(xiàn)在的正則引擎實(shí)現(xiàn),允許定義對一個字符重復(fù)多少次。語法是:{min,max}。min和max都是非負(fù)整數(shù)。如果逗號有而max被忽略了,則max沒有限制。如果逗號和max都被忽略了,則重復(fù)min次。 因此{0,}和*一樣,{1,}和+ 的作用一樣。 你可以用\b[1-9][0-9]{3}\b匹配1000~9999之間的數(shù)字(“\b”表示單詞邊界)。\b[1-9][0-9]{2,4}\b匹配一個在100~99999之間的數(shù)字。 注意貪婪性 假設(shè)用一個正則式去匹配一個HTML標(biāo)簽。知道輸入將會是一個有效的HTML文件,因此正則式不需要排除那些無效的標(biāo)簽。所以如果是兩個尖括號之間的內(nèi)容,就應(yīng)該是一個HTML標(biāo)簽。 很多正則式的新手首先會想到用正則式 <.+> ,他們會很驚訝的發(fā)現(xiàn),對于測試字符串,“This is a <EM>first</EM> test”,你可能期望會返回<EM>,然后繼續(xù)進(jìn)行匹配的時候,返回</EM>。但事實(shí)不會。正則式將會匹配“<EM>first</EM>”。顯然這不是我們想要的結(jié)果。 原因在于“+”是貪婪的。也就是說,“+”會導(dǎo)致正則引擎試圖盡可能地重復(fù)前導(dǎo)字符。只有當(dāng)這種重復(fù)會引起整個正則表達(dá)式匹配失敗的情況下,引擎會進(jìn)行回溯。也就是說,它會放棄最后一次的“重復(fù)”,然后處理正則表達(dá)式余下的部分。 和“+”類似,“?”“*”的重復(fù)也是貪婪的。 14、分組與后向引用(Grouping and Backreference)使用圓括號進(jìn)行分組 使用圓括號創(chuàng)建后向引用 “()”在分組的同時,也會創(chuàng)建一個“后向引用”,一個“后向引用”保存的是一個分組內(nèi)正則表達(dá)式匹配的字符串。 在定義了一個正則表達(dá)式組的同時,“()”也創(chuàng)建了一個后向引用。一個后向引用保存了由"()"內(nèi)的正則式匹配到的字符串。 除非你使用“非捕獲”的“()”,否則該“()”會形成一個后向引用。這里記住后向引用會減慢正則引擎的速度,因?yàn)樗枰瓿梢恍╊~外的操作。如果你不使用后向引用,你可以使用非捕獲的“()”來提高正則引擎的工作速度,但這樣做的代價(jià)是會使你的正則式的易讀性降低。 正則式"Set(Value)?"匹配"Set"或"SetValue"。在第一種情況中,第一個后向引用(這里也只有一個后向引用)是空的,因?yàn)樗鼪]有匹配任何字符串。在第二種情況中,第一個后向引用將會保存"Value"。 如何使用后向引用 后向引用允許你重復(fù)使用后向引用中保存的內(nèi)容??梢杂谩癨數(shù)字”的方式進(jìn)行引用。"\1"引用第一個匹配的后向引用組,"\2"引用第二個組,以此類推,"\n"引用第n個組。而"\0"則引用整個被匹配的正則表達(dá)式本身。 在正則式中使用后向引用 假設(shè)你想匹配一個HTML標(biāo)簽的開始標(biāo)簽和結(jié)束標(biāo)簽,以及標(biāo)簽中間的文本。比如<B>This is a test</B>,我們要匹配<B>和</B>以及中間的文字。我們可以用如下正則表達(dá)式:“<([A-Z][A-Z0-9]*)[^>]*>.*?</\1>” 你可以對相同的后向引用組進(jìn)行多次引用,"([a-c])x\1x\1"將匹配“axaxa”、“bxbxb”以及“cxcxc”。如果用數(shù)字形式引用的組沒有有效的匹配,則引用到的內(nèi)容簡單的為空。 一個后向引用不能用于它自身。"([abc]\1)"是錯誤的。因此你不能將"\0"用于一個正則表達(dá)式匹配本身,它只能用于替換操作中。 后向引用不能用于字符集內(nèi)部。"(a)[\1b]"中的"\1"并不表示后向引用。在字符集內(nèi)部,"\1"可以被解釋為八進(jìn)制形式的轉(zhuǎn)碼。 重復(fù)操作與后向引用 當(dāng)對組使用重復(fù)操作符時,緩存里后向引用內(nèi)容會被不斷刷新,只保留最后匹配的內(nèi)容。如果"()"中的正則式找到一個新的匹配,則后向引用中的內(nèi)容會被覆蓋。"([abc]+) "和"([abc])+"就有著明顯的差別。對于字符串"abc",兩個正則式都會匹配成功。第一個正則式將會把"abc"置于后向引用中,而第二個正則式僅會把"b"置于后向引種中。因?yàn)樵诘诙€正則式中,"+"會導(dǎo)致"()"重復(fù)匹配3次,第一次"a"被保存,第二次"b"被保存,第三次"c"被保存,每一次,前一次的值都被覆蓋。 這也意味著對于字符串"cab=cab", 正則式"([abc]+)=\1"會匹配成功,而"([abc])+=\1"則不能匹配成功。 后向引用使用實(shí)例 當(dāng)編輯文字時,很容易就會輸入重復(fù)單詞,例如"the the"。使用"\b(\w+)\s+\1\b"可以檢測到這些重復(fù)單詞。要刪除第二個單詞,只要簡單的利用替換功能,用"\1"替換就可以了。 15、正則表達(dá)式實(shí)戰(zhàn)訓(xùn)練3問題: 字符串中1個或者連續(xù)多個空格替換成一個Tab鍵
分析: 由于字符串中連續(xù)的空格的個數(shù)不太確定,如果我們逐個字符去分析的話,也是比較麻煩的,但如果用正則去實(shí)現(xiàn),則簡單的多。這也是一個典型的適合用正則解決的問題。解決方式如下:
16、正則表達(dá)式實(shí)戰(zhàn)訓(xùn)練4問題:查找字符串中連續(xù)9個數(shù)字字符并顯示其開始位置。
17、實(shí)用的正則查找封裝函數(shù)這是一個封裝的查找函數(shù),使用正則實(shí)現(xiàn)查找功能,函數(shù)實(shí)現(xiàn)如下,使用時,把下面的函數(shù)置于VBA工程的普通模塊中,就可以在代碼中引用或者在單元格中直接使用函數(shù)
18、實(shí)用的正則替換封裝函數(shù)這是一個封裝的替換函數(shù),使用正則實(shí)現(xiàn)替換功能,函數(shù)實(shí)現(xiàn)如下,使用時,把下面的函數(shù)置于VBA工程的普通模塊中,就可以在代碼中引用或者在單元格中直接使用函數(shù)
19、正則表達(dá)式實(shí)戰(zhàn)訓(xùn)練5問題:判斷一個郵件地址格式是否有效
|
|