摘要:選擇分組和引用正則表達式的語法還包括指定選擇項子表達式分組和引用前一子表達式的特殊字符。帶圓括號的表達式的另一個用途是允許在同一正則表達式的后部引用前面的子表達式。
正則表達式(regular expression)是一個描述字符模式的對象。JavaScript的 RegExp類 表示正則表達式,String和RegExp都定義了方法,后者使用正則表達式進 行強大的模式匹配和文本檢索與替換功能。JavaScript的正則表達式語法是Perl5的正則表達式語法的大型子集,所以對于有Perl編程經驗的程序員來說,學習JavaScript 中的正則表達式[1]是小菜一碟。
定義JavaScript中的正則表達式用 RegExp對象 表示,可以使用RegExp()構造函數來創 建RegExp對象,不過RegExp對象更多的是通過一種特殊的直接量語法來創建。就像通過引號包裹字符的方式來定義字符串直接量一樣,正則表達式直接量定義為包含在一對斜杠 (/) 之間的字符,例如:
var pattern=/s$/;
運行這段代碼創建一個新的RegExp對象,并將它賦值給變量pattern。這個特殊 的RegExp對象用來匹配所有以字母“s”結尾的字符串。用構造函數RegExp()也可以 定義個與之等價的正則表達式,代碼如下:
var pattern=new RegExp(“s$”);
正則表達式直接量則與此不同,ECMAScript 3規范規定,一個正則表達式直接 量會在執行到它時轉換為一個RegExp對象,同一段代碼所表示正則表達式直接量的 每次運算都返回同一個對象。ECMAScript 5規范則做了相反的規定,同一段代碼所 表示的正則表達式直接量的每次運算都返回新對象。IE一直都是按照ECMAScript 5 規范實現的,多數最新版本的瀏覽器也開始遵循ECMAScript 5。
高級語法 非貪婪的重復一般匹配重復字符是盡可能多地匹配,而且允許后續的正則表達式 繼續匹配。因此,我們稱之為“貪婪的”匹配。我們同樣可以使用正則表達式進行非貪婪匹配。只須在待匹配的字符后跟隨一個問號即 可:“??”、“+?”、“*?”或“{1,5}?”。比如,正則表達式/a+/可以匹配一個或多個連續 的字母a。當使用“aaa”作為匹配字符串時,正則表達式會匹配它的三個字符。但 是/a+?/也可以匹配一個或多個連續字母a,但它是盡可能少地匹配。我們同樣 將“aaa”作為匹配字符串,但后一個模式只能匹配第一個a。
使用非貪婪的匹配模式所得到的結果可能和期望并不一致。考慮以下正則表達 式/a+b/,它可以匹配一個或多個a,以及一個b。當使用“aaab”作為匹配字符串時, 它會匹配整個字符串。現在再試一下非貪婪匹配的版本/a+?b/,它匹配盡可能少的a 和一個b。當用它來匹配“aaab”時,你期望它能匹配一個a和最后一個b。但實際上, 這個模式卻匹配了整個字符串,和該模式的貪婪匹配一模一樣。這是因為正則表達 式的模式匹配總是會尋找字符串中第一個可能匹配的位置。由于該匹配是從字符串的第一個字符開始的,因此在這里不考慮它的子串中更短的匹配。
選擇、分組和引用正則表達式的語法還包括指定選擇項、子表達式分組和引用前一子表達式的特殊字符。字符“|”用于分隔供選擇的字符。例如,/ab|cd|ef/ 可以匹配字符串“ab”,也 可以匹配字符串“cd”,還可以匹配字符串“ef”。/d{3}|[a-z]{4}/匹配的是三位數字或 者四個小寫字母。
注意,選擇項的嘗試匹配次序是從左到右,直到發現了匹配項。如果左邊的選擇項匹配,就忽略右邊的匹配項,即使它產生更好的匹配。因此,當正則表達式 /a|ab/匹配字符串“ab”時,它只能匹配第一個字符。
正則表達式中的圓括號有多種作用。一個作用是把多帶帶的項組合成子表達式, 以便可以像處理一個獨立的單元那樣用“|”、“*”、“+”或者“?”等來對單元內的項進行處理。例如, /java(script)?/ 可以匹配字符串“java”,其后可以有“script”也可以沒有。/(ab|cd)+|ef/ 可以匹配字符串“ef”,也可以匹配字符串“ab”或“cd”的一次或多次重復。
在正則表達式中,圓括號的另一個作用是在完整的模式中定義子模式。當一個正則表達式成功地和目標字符串相匹配時,可以從目標串中抽出和圓括號中的子模式相匹配的部分。例如,假定我們正在檢索的模式是一個或多個小寫字母后面跟隨了一位或多位數字, 則可以使用模式 /[a-z]+d+/。但假定我們真正關心的是每個匹配尾部的數字,那么如果將模式的數字部分放在括號中 (/[a-z]+(d+)/) ,就可以從檢索到的匹配中抽取數字 了,之后我們會有詳盡的解釋。
帶圓括號的表達式的另一個用途是允許在同一正則表達式的后部引用前面的子表達式。這是通過在字符 “” 后加一位或多位數字來實現的。這個數字指定了帶圓括 號的子表達式在正則表達式中的位置。例如,1引用的是第一個帶圓括號的子表達 式,3 引用的是第三個帶圓括號的子表達式。注意,因為子表達式可以嵌套另一個子表達式,所以它的位置是參與計數的左括號的位置。例如,在下面的正則表達式 中,嵌套的子表達式 ([Ss]cript) 可以用 2來指代:
/([Jj]ava([Ss]cript)?)siss(funw*)/
對正則表達式中前一個子表達式的引用,并不是指對子表達式模式的引用,而指的是與那個模式相匹配的文本的引用。這樣,引用可以用于實施一條約束,即一個字符串各個多帶帶部分包含的是完全相同的字符。例如,下面的正則表達式匹配的就是位于單引號或雙引號之內的0個或多個字符。但是,它并不要求左側和右側的引號匹配(即,加入的兩個引號都是單引號或都是雙引號):
/[’”][^’”]*[’”]/
如果要匹配左側和右側的引號,可以使用如下的引用:
/([’”])[^’”]*1/
1 匹配的是第一個帶圓括號的子表達式所匹配的模式。在這個例子中,存在這樣一條約束,那就是左側的引號必須和右側的引號相匹配。正則表達式不允許用雙引號括起的內容中有單引號,反之亦然。不能在字符類中使用這種引用,所以下面的寫法是非法的:
/([’”])[^1]*1/
同樣,在正則表達式中不用創建帶數字編碼的引用,也可以對子表達式進行分組。它不是以“(”和“)”進行分組,而是以“(?:”和“)”來進行分組,比如,考慮下面這 個模式:
/([Jj]ava(?:[Ss]cript)?)siss(funw*)/
這里,子表達式 (?:[Ss]cript) 僅僅用于分組,因此復制符號”?”可以應用到各個分 組。這種改進的圓括號并不生成引用,所以在這個正則表達式中,2 引用了與 (funW*) 匹配的文本。
下圖對正則表達式的選擇、分組和引用運算符做了總結:
先行斷言任意正則表達式都可以作為錨點條件。如果在符號 “(?=”和“)” 之間加入一個表 達式,它就是一個 先行斷言 ,用以說明圓括號內的表達式必須正確匹配,但并不是真正意義上的匹配。比如,要匹配一種常用的程序設計語言的名字,但只在其后 有冒號時才匹配,可以使用 /[Jj]ava([Ss]cript)?(?=:)/。這個正則表達式可以匹 配“JavaScript:The Definitive Guide”中的“JavaScript”,但是不能匹配“Java in a Nutshell”中的“Java”,因為它后面沒有冒號。
帶有 “(?!” 的斷言是負向先行斷言,用以指定接下來的字符都不必匹配。例 如, /Java(?!Script)([A-Z]w*)/可以匹配“Java”后跟隨一個大寫字母和任意多個ASCII 單詞,但Java后面不能跟隨“Script”。它可以匹配“JavaBeans”,但不能匹配“Javanese”;它不匹配“JavaScript”,也不能匹配“JavaScripter”。
用于模式匹配的String方法String支持4種使用正則表達式的方法。
search最簡單的是 search()。它的參數是一個正 則表達式,返回第一個與之匹配的子串的起始位置,如果找不到匹配的子串,它將 返回-1。比如,下面的調用返回值為4:
“JavaScript”.search(/script/i);
如果search()的參數不是正則表達式,則首先會通過RegExp構造函數將它轉換 成正則表達式, search()方法不支持全局檢索,因為它忽略正則表達式參數中的修飾符g。
replacereplace()方法用以執行檢索與替換操作。其中第一個參數是一個正則表達式, 第二個參數是要進行替換的字符串。這個方法會對調用它的字符串進行檢索,使用指定的模式來匹配。如果正則表達式中設置了修飾符g,那么源字符串中所有與模式匹配的子串都將替換成第二個參數指定的字符串;如果不帶修飾符g,則只替換所匹配的第一個子串。如果replace()的第一個參數是字符串而不是正則表達式,則 replace()將直接搜索這個字符串,而不是像search()一樣首先通過RegExp()將它轉換為正則表達式。比如,可以使用下面的方法,利用replace()將文本中的所有 javascript(不區分大小寫)統一替換為“JavaScript”:
//將所有不區分大小寫的javascript都替換成大小寫正確的JavaScript text.replace(/javascript/gi,“JavaScript”);
但 replace() 的功能遠不止這些。回憶一下前文所提到的,正則表達式中使用圓 括號括起來的子表達式是帶有從左到右的索引編號的,而且正則表達式會記憶與每 個子表達式匹配的文本。如果在替換字符串中出現了$加數字,那么 replace() 將用與 指定的子表達式相匹配的文本來替換這兩個字符。這是一個非常有用的特性。比 如,可以用它將一個字符串中的英文引號替換為中文半角引號:
//一段引用文本起始于引號,結束于引號 //中間的內容區域不能包含引號 var quote=/”([^”]*)”/g;//用中文半角引號替換英文引號,同時要保持引號之間的內容(存儲在$1中)沒有被修改 text.replace(quote,’“$1”’);
最值得注意的是,replace()方法的第二個參數 可以是函數,該函數能夠動態地計算替換字符串。
matchmatch() 方法是最常用的String正則表達式方法。它的唯一參數就是一個正則表達式(或通過RegExp()構造函數將其轉換為正則表達式),返回的是一個由匹配結 果組成的數組。如果該正則表達式設置了修飾符g,則該方法返回的數組包含字符 串中的所有匹配結果。例如:
“1 plus 2 equals 3”.match(/d+/g)//返回[“1”,“2”,“3”]
如果這個正則表達式沒有設置修飾符 g, match() 就不會進行全局檢索,它只檢 索第一個匹配。但即使 match() 執行的不是全局檢索,它也返回一個數組。在這種情 況下,數組的第一個元素就是匹配的字符串,余下的元素則是正則表達式中用圓括 號括起來的子表達式。因此,如果 match() 返回一個數組a,那么 a[0] 存放的是完整的 匹配,a[1]存放的則是與第一個用圓括號括起來的表達式相匹配的子串,以此類 推。為了和方法 replace() 保持一致, a[n] 存放的是 $n的內容。
splitsplit() 這個方法用以將調用 它的字符串拆分為一個子串組成的數組,使用的分隔符是split()的參數,例如:
“123,456,789”.split(“,”);//返回[“123”,“456”,“789”]
split() 方法的參數也可以是一個正則表達式,這使得 split() 方法異常強大。例如,可以指定分隔符,允許兩邊可以留有任意多的空白符:
“1,2,3,4,5”.split(/s*,s*/);//返回[“1”,“2”,“3”,“4”,“5”]RegExp對象 RegExp的屬性
每個RegExp對象都包含5個屬性。
屬性source是一個只讀的字符串,包含正則表達式的文本。
屬性global是一個只讀的布爾值,用以說明這個正則表達式是否帶有修飾符 g。
屬性 ignoreCase 也是一個只讀的布爾值,用以說明正則表達式是否帶有修飾符 i。
屬性 multiline 是一個只讀的布爾值,用以說明正則表達式是否帶有修飾符 m。
最后一個屬性 lastIndex,它是一個可讀/寫的整數。如果匹配模式帶有g修飾符, 這個屬性存儲在整個字符串中下一次檢索的開始位置,這個屬性會被 exec()和 test() 方法用到,下面會講到。
RegExp的方法RegExp對象定義了兩個用于執行模式匹配操作的方法。
execRegExp最主要的執行模式匹配的方法是 exec() ,exec()方法對一個指定的字符串執行一個正則表達 式,簡言之,就是在一個字符串中執行匹配檢索。如果它沒有找到任何匹配,它就 返回null,但如果它找到了一個匹配,它將返回一個數組,就像match() 方法為非全局檢索返回的數組一樣。
和 match() 方法不同,不管正則表達式是否具有全局修飾符g, exec()都會返回一樣的數組。當調用exec()的正則表達式對象具有修飾符g時,它將把當前正則表達式 對象的lastIndex屬性設置為緊挨著匹配子串的字符位置。當同一個正則表達式第二 次調用 exec() 時,它將從 lastIndex 屬性所指示的字符處開始檢索。
var pattern = /Java/g; var text = "JavaScript is more fun than Java!"; result = pattern.exec(text) //結果 //["Java", index: 0, input: "JavaScript is more fun than Java!"] pattern.lastIndex //4
如果 exec() 沒有發現任何匹配結果,它會將 lastIndex 重置為0(在任何時候都可以將 lastIndex屬性設置 為0,每當在字符串中找最后一個匹配項后,在使用這個RegExp對象開始新的字符串查找之前,都應當將 lastIndex 設置為0)。這種特殊的行為使我們可以在用正則表達式匹配字符串的過程中反復調用 exec(),比如:
var pattern = /Java/g; var text = "JavaScript is more fun than Java!"; var result; while ((result = pattern.exec(text)) != null) { alert("Matched "" + result[0] + """ + " at position " + result.index + "; next search begins at " + pattern.lastIndex); }test
另外一個RegExp方法是 test() ,它比 exec() 更簡單一些。它的參數是一個字符串,用 test() 對某個字符串進行檢測,如果包含正則表達式的一個匹配結果,則返回 true :
var pattern=/java/i; pattern.test(“JavaScript”);//返回true
調用 test() 和調用 exec() 等價,當 exec() 的返回結果不是null時,test()返回true。由于這種等價性,當一個全局正則表達式調用方法 test() 時,它的行為和 exec() 相同, 因為它從 lastIndex 指定的位置處開始檢索某個字符串,如果它找到了一個匹配結果,那么它就立即設置 lastIndex 為當前匹配子串的結束位置。這樣一來,就可以使用test() 來遍歷字符串,就像用 exec() 方法一樣。
與 exec() 和 test() 不同, String方法 search()、replace() 和 match() 并不會用到 lastIndex 屬性。實際上, String 方法只是簡單地將 lastIndex 屬性值重置為0。如果讓一 個帶有修飾符 g 的正則表達式對多個字符串執行 exec()或test(),要么在每個字符串中 找出所有的匹配以便將 lastIndex 自動重置為零,要么顯式將 lastIndex 手動設置為 0(當最后一次檢索失敗時需要手動設置 lastIndex )。
如果忘了手動設置 lastIndex 的值,那么下一次對新字符串進行檢索時,執行檢索的起始位置可能就不是字符串的 開始位置,而可能是任意位置。當然,如果RegExp不帶有修飾符g,則不必擔心會發生這種情況。同樣要記住,在 ECMAScript 5中,正則表達式直接量的每次計算都會創建一個新的 RegExp對象,每個新 RegExp對象 具有各自的 lastIndex屬性,這勢必會大大減少“殘留” lastIndex 對程序造成的意外影響。
參考JavaScript 權威指南第六版
玩轉JavaScript正則表達式
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/84892.html
摘要:正則表達式的意義中的正則表達式使用表示,可以使用構造函數來創建對象,不過對象更多的是通過一種特殊的直接量語法來創建。用構造函數也可以定義一個與之等價的正則表達式,代碼如下正則表達式的模式規則是由一個字符序列組成的。 正則表達式的模式匹配 正則表達式(regular expression)是一個描述字符模式的對象。javascript的RegExp對象表示正則表達式,String和Reg...
摘要:引用就是允許在同一個正則表達式的后部引用前面的子表達式。這個數字制定了帶圓括號的子表達式在正則表達式中的位置。對正則表達式中前一個子表達式的引用,并不是指對子表達式模式的引用,而是指與那個模式匹配的文本的引用。 前言 本文主要是在讀《JavaScript高級程序語言設計》一書有關正則表達式的章節的知識點記錄,方便后續查閱。 什么是正則表達式 正則表達式是用來描述字符組合的某種規則。它可...
摘要:正則表達式的字符串表示,按照字面量形式而非傳入構造函數中的字符串模式返回。其中,表示匹配項在字符串中的位置,而表示應用正則表達式的字符串。下面列出了正則表達式所不支持的特性。關卡按要求完成下列常用的正則表達式。 由于本課程的核心是 JavaScript,所以本文著重講解了「正則表達式」在 JavaScript 中的用法,并未深入「正則表達式」的具體細節。如果您尚不了解「正則表達式」,強...
摘要:目錄導語理解正則表達式模式的規則字符串和正則實例的屬性和方法檢索實例小結導語正則表達式是處理字符串的一門藝術手法,應用場景經常出現在表單驗證部分高級程序設計一書開篇提到,這門語言最原始的應用就是處理輸入驗證操作,所以正則表達式從誕生那一刻就 目錄 導語 1.理解正則表達式 2.模式的規則 3.字符串和正則實例的屬性和方法 4.檢索實例 5. 小結 導語 正則表達式是處理字符串的一門藝...
摘要:當正則表達式是靜態不變的,那么使用這種方式將會獲得更好的性能。使用正則表達式在中,正則表達式是通過對象的和方法以及字符串內置的,,,方法使用的。這些標志可以以任何順序單獨使用或一起使用,并作為正則表達式的一部分。 版權聲明:本文由吳仙杰創作整理,轉載請注明出處:https://segmentfault.com/a/1190000009169325 1. 引言 正則表達式本身語法是一致,...
閱讀 2772·2021-10-14 09:42
閱讀 827·2021-10-11 10:57
閱讀 773·2019-08-30 15:54
閱讀 1914·2019-08-30 13:50
閱讀 1685·2019-08-30 11:19
閱讀 932·2019-08-29 12:38
閱讀 1425·2019-08-26 11:51
閱讀 1388·2019-08-26 10:48