成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JavaScript正則表達式的匹配模式

wqj97 / 746人閱讀

摘要:選擇分組和引用正則表達式的語法還包括指定選擇項子表達式分組和引用前一子表達式的特殊字符。帶圓括號的表達式的另一個用途是允許在同一正則表達式的后部引用前面的子表達式。

正則表達式(regular expression)是一個描述字符模式的對象。JavaScript的 RegExp類 表示正則表達式,String和RegExp都定義了方法,后者使用正則表達式進 行強大的模式匹配文本檢索與替換功能。JavaScript的正則表達式語法是Perl5的正則表達式語法的大型子集,所以對于有Perl編程經(jīng)驗的程序員來說,學(xué)習(xí)JavaScript 中的正則表達式[1]是小菜一碟。

定義

JavaScript中的正則表達式用 RegExp對象 表示,可以使用RegExp()構(gòu)造函數(shù)來創(chuàng) 建RegExp對象,不過RegExp對象更多的是通過一種特殊的直接量語法來創(chuàng)建。就像通過引號包裹字符的方式來定義字符串直接量一樣,正則表達式直接量定義為包含在一對斜杠 (/) 之間的字符,例如:

var pattern=/s$/;

運行這段代碼創(chuàng)建一個新的RegExp對象,并將它賦值給變量pattern。這個特殊 的RegExp對象用來匹配所有以字母“s”結(jié)尾的字符串。用構(gòu)造函數(shù)RegExp()也可以 定義個與之等價的正則表達式,代碼如下:

var pattern=new RegExp(“s$”);

正則表達式直接量則與此不同,ECMAScript 3規(guī)范規(guī)定,一個正則表達式直接 量會在執(zhí)行到它時轉(zhuǎn)換為一個RegExp對象,同一段代碼所表示正則表達式直接量的 每次運算都返回同一個對象。ECMAScript 5規(guī)范則做了相反的規(guī)定,同一段代碼所 表示的正則表達式直接量的每次運算都返回新對象。IE一直都是按照ECMAScript 5 規(guī)范實現(xiàn)的,多數(shù)最新版本的瀏覽器也開始遵循ECMAScript 5。

高級語法 非貪婪的重復(fù)

一般匹配重復(fù)字符是盡可能多地匹配,而且允許后續(xù)的正則表達式 繼續(xù)匹配。因此,我們稱之為“貪婪的”匹配。我們同樣可以使用正則表達式進行非貪婪匹配。只須在待匹配的字符后跟隨一個問號即 可:“??”、“+?”、“*?”或“{1,5}?”。比如,正則表達式/a+/可以匹配一個或多個連續(xù) 的字母a。當(dāng)使用“aaa”作為匹配字符串時,正則表達式會匹配它的三個字符。但 是/a+?/也可以匹配一個或多個連續(xù)字母a,但它是盡可能少地匹配。我們同樣 將“aaa”作為匹配字符串,但后一個模式只能匹配第一個a。

使用非貪婪的匹配模式所得到的結(jié)果可能和期望并不一致。考慮以下正則表達 式/a+b/,它可以匹配一個或多個a,以及一個b。當(dāng)使用“aaab”作為匹配字符串時, 它會匹配整個字符串。現(xiàn)在再試一下非貪婪匹配的版本/a+?b/,它匹配盡可能少的a 和一個b。當(dāng)用它來匹配“aaab”時,你期望它能匹配一個a和最后一個b。但實際上, 這個模式卻匹配了整個字符串,和該模式的貪婪匹配一模一樣。這是因為正則表達 式的模式匹配總是會尋找字符串中第一個可能匹配的位置。由于該匹配是從字符串的第一個字符開始的,因此在這里不考慮它的子串中更短的匹配。

選擇、分組和引用

正則表達式的語法還包括指定選擇項、子表達式分組引用前一子表達式的特殊字符。字符“|”用于分隔供選擇的字符。例如,/ab|cd|ef/ 可以匹配字符串“ab”,也 可以匹配字符串“cd”,還可以匹配字符串“ef”。/d{3}|[a-z]{4}/匹配的是三位數(shù)字或 者四個小寫字母。

注意,選擇項的嘗試匹配次序是從左到右,直到發(fā)現(xiàn)了匹配項。如果左邊的選擇項匹配,就忽略右邊的匹配項,即使它產(chǎn)生更好的匹配。因此,當(dāng)正則表達式 /a|ab/匹配字符串“ab”時,它只能匹配第一個字符。

正則表達式中的圓括號有多種作用。一個作用是把多帶帶的項組合成子表達式, 以便可以像處理一個獨立的單元那樣用“|”、“*”、“+”或者“?”等來對單元內(nèi)的項進行處理。例如, /java(script)?/ 可以匹配字符串“java”,其后可以有“script”也可以沒有。/(ab|cd)+|ef/ 可以匹配字符串“ef”,也可以匹配字符串“ab”或“cd”的一次或多次重復(fù)。

在正則表達式中,圓括號的另一個作用是在完整的模式中定義子模式。當(dāng)一個正則表達式成功地和目標(biāo)字符串相匹配時,可以從目標(biāo)串中抽出和圓括號中的子模式相匹配的部分。例如,假定我們正在檢索的模式是一個或多個小寫字母后面跟隨了一位或多位數(shù)字, 則可以使用模式 /[a-z]+d+/。但假定我們真正關(guān)心的是每個匹配尾部的數(shù)字,那么如果將模式的數(shù)字部分放在括號中 (/[a-z]+(d+)/) ,就可以從檢索到的匹配中抽取數(shù)字 了,之后我們會有詳盡的解釋。

帶圓括號的表達式的另一個用途是允許在同一正則表達式的后部引用前面的子表達式。這是通過在字符 “” 后加一位或多位數(shù)字來實現(xiàn)的。這個數(shù)字指定了帶圓括 號的子表達式在正則表達式中的位置。例如,1引用的是第一個帶圓括號的子表達 式,3 引用的是第三個帶圓括號的子表達式。注意,因為子表達式可以嵌套另一個子表達式,所以它的位置是參與計數(shù)的左括號的位置。例如,在下面的正則表達式 中,嵌套的子表達式 ([Ss]cript) 可以用 2來指代:

/([Jj]ava([Ss]cript)?)siss(funw*)/

對正則表達式中前一個子表達式的引用,并不是指對子表達式模式的引用,而指的是與那個模式相匹配的文本的引用。這樣,引用可以用于實施一條約束,即一個字符串各個多帶帶部分包含的是完全相同的字符。例如,下面的正則表達式匹配的就是位于單引號或雙引號之內(nèi)的0個或多個字符。但是,它并不要求左側(cè)和右側(cè)的引號匹配(即,加入的兩個引號都是單引號或都是雙引號):

/[’”][^’”]*[’”]/

如果要匹配左側(cè)和右側(cè)的引號,可以使用如下的引用:

/([’”])[^’”]*1/

1 匹配的是第一個帶圓括號的子表達式所匹配的模式。在這個例子中,存在這樣一條約束,那就是左側(cè)的引號必須和右側(cè)的引號相匹配。正則表達式不允許用雙引號括起的內(nèi)容中有單引號,反之亦然。不能在字符類中使用這種引用,所以下面的寫法是非法的:

/([’”])[^1]*1/

同樣,在正則表達式中不用創(chuàng)建帶數(shù)字編碼的引用,也可以對子表達式進行分組。它不是以“(”和“)”進行分組,而是以“(?:”和“)”來進行分組,比如,考慮下面這 個模式:

/([Jj]ava(?:[Ss]cript)?)siss(funw*)/

這里,子表達式 (?:[Ss]cript) 僅僅用于分組,因此復(fù)制符號”?”可以應(yīng)用到各個分 組。這種改進的圓括號并不生成引用,所以在這個正則表達式中,2 引用了與 (funW*) 匹配的文本。

下圖對正則表達式的選擇、分組和引用運算符做了總結(jié):

先行斷言

任意正則表達式都可以作為錨點條件。如果在符號 “(?=”和“)” 之間加入一個表 達式,它就是一個 先行斷言 ,用以說明圓括號內(nèi)的表達式必須正確匹配,但并不是真正意義上的匹配。比如,要匹配一種常用的程序設(shè)計語言的名字,但只在其后 有冒號時才匹配,可以使用 /[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()。它的參數(shù)是一個正 則表達式,返回第一個與之匹配的子串的起始位置,如果找不到匹配的子串,它將 返回-1。比如,下面的調(diào)用返回值為4:

“JavaScript”.search(/script/i);

如果search()的參數(shù)不是正則表達式,則首先會通過RegExp構(gòu)造函數(shù)將它轉(zhuǎn)換 成正則表達式, search()方法不支持全局檢索,因為它忽略正則表達式參數(shù)中的修飾符g。

replace

replace()方法用以執(zhí)行檢索與替換操作。其中第一個參數(shù)是一個正則表達式, 第二個參數(shù)是要進行替換的字符串。這個方法會對調(diào)用它的字符串進行檢索,使用指定的模式來匹配。如果正則表達式中設(shè)置了修飾符g,那么源字符串中所有與模式匹配的子串都將替換成第二個參數(shù)指定的字符串;如果不帶修飾符g,則只替換所匹配的第一個子串。如果replace()的第一個參數(shù)是字符串而不是正則表達式,則 replace()將直接搜索這個字符串,而不是像search()一樣首先通過RegExp()將它轉(zhuǎn)換為正則表達式。比如,可以使用下面的方法,利用replace()將文本中的所有 javascript(不區(qū)分大小寫)統(tǒng)一替換為“JavaScript”:

//將所有不區(qū)分大小寫的javascript都替換成大小寫正確的JavaScript 
text.replace(/javascript/gi,“JavaScript”);

replace() 的功能遠不止這些?;貞浺幌虑拔乃岬降?,正則表達式中使用圓 括號括起來的子表達式是帶有從左到右的索引編號的,而且正則表達式會記憶與每 個子表達式匹配的文本。如果在替換字符串中出現(xiàn)了$加數(shù)字,那么 replace() 將用與 指定的子表達式相匹配的文本來替換這兩個字符。這是一個非常有用的特性。比 如,可以用它將一個字符串中的英文引號替換為中文半角引號:

//一段引用文本起始于引號,結(jié)束于引號
//中間的內(nèi)容區(qū)域不能包含引號
var quote=/”([^”]*)”/g;//用中文半角引號替換英文引號,同時要保持引號之間的內(nèi)容(存儲在$1中)沒有被修改 
text.replace(quote,’“$1”’);

最值得注意的是,replace()方法的第二個參數(shù) 可以是函數(shù),該函數(shù)能夠動態(tài)地計算替換字符串。

match

match() 方法是最常用的String正則表達式方法。它的唯一參數(shù)就是一個正則表達式(或通過RegExp()構(gòu)造函數(shù)將其轉(zhuǎn)換為正則表達式),返回的是一個由匹配結(jié) 果組成的數(shù)組。如果該正則表達式設(shè)置了修飾符g,則該方法返回的數(shù)組包含字符 串中的所有匹配結(jié)果。例如:

“1 plus 2 equals 3”.match(/d+/g)//返回[“1”,“2”,“3”]

如果這個正則表達式?jīng)]有設(shè)置修飾符 g, match() 就不會進行全局檢索,它只檢 索第一個匹配。但即使 match() 執(zhí)行的不是全局檢索,它也返回一個數(shù)組。在這種情 況下,數(shù)組的第一個元素就是匹配的字符串,余下的元素則是正則表達式中用圓括 號括起來的子表達式。因此,如果 match() 返回一個數(shù)組a,那么 a[0] 存放的是完整的 匹配,a[1]存放的則是與第一個用圓括號括起來的表達式相匹配的子串,以此類 推。為了和方法 replace() 保持一致, a[n] 存放的是 $n的內(nèi)容。

split

split() 這個方法用以將調(diào)用 它的字符串拆分為一個子串組成的數(shù)組,使用的分隔符是split()的參數(shù),例如:

“123,456,789”.split(“,”);//返回[“123”,“456”,“789”]

split() 方法的參數(shù)也可以是一個正則表達式,這使得 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,它是一個可讀/寫的整數(shù)。如果匹配模式帶有g(shù)修飾符, 這個屬性存儲在整個字符串中下一次檢索的開始位置,這個屬性會被 exec()test() 方法用到,下面會講到。

RegExp的方法

RegExp對象定義了兩個用于執(zhí)行模式匹配操作的方法。

exec

RegExp最主要的執(zhí)行模式匹配的方法是 exec()exec()方法對一個指定的字符串執(zhí)行一個正則表達 式,簡言之,就是在一個字符串中執(zhí)行匹配檢索。如果它沒有找到任何匹配,它就 返回null,但如果它找到了一個匹配,它將返回一個數(shù)組,就像match() 方法為非全局檢索返回的數(shù)組一樣。

match() 方法不同,不管正則表達式是否具有全局修飾符g, exec()都會返回一樣的數(shù)組。當(dāng)調(diào)用exec()的正則表達式對象具有修飾符g時,它將把當(dāng)前正則表達式 對象的lastIndex屬性設(shè)置為緊挨著匹配子串的字符位置。當(dāng)同一個正則表達式第二 次調(diào)用 exec() 時,它將從 lastIndex 屬性所指示的字符處開始檢索。

var pattern = /Java/g;
var text = "JavaScript is more fun than Java!";
result = pattern.exec(text)
//結(jié)果
//["Java", index: 0, input: "JavaScript is more fun than Java!"]
pattern.lastIndex //4

如果 exec() 沒有發(fā)現(xiàn)任何匹配結(jié)果,它會將 lastIndex 重置為0(在任何時候都可以將 lastIndex屬性設(shè)置 為0,每當(dāng)在字符串中找最后一個匹配項后,在使用這個RegExp對象開始新的字符串查找之前,都應(yīng)當(dāng)將 lastIndex 設(shè)置為0)。這種特殊的行為使我們可以在用正則表達式匹配字符串的過程中反復(fù)調(diào)用 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() 更簡單一些。它的參數(shù)是一個字符串,用 test() 對某個字符串進行檢測,如果包含正則表達式的一個匹配結(jié)果,則返回 true :

var pattern=/java/i; 
pattern.test(“JavaScript”);//返回true

調(diào)用 test() 和調(diào)用 exec() 等價,當(dāng) exec() 的返回結(jié)果不是null時,test()返回true。由于這種等價性,當(dāng)一個全局正則表達式調(diào)用方法 test() 時,它的行為和 exec() 相同, 因為它從 lastIndex 指定的位置處開始檢索某個字符串,如果它找到了一個匹配結(jié)果,那么它就立即設(shè)置 lastIndex 為當(dāng)前匹配子串的結(jié)束位置。這樣一來,就可以使用test() 來遍歷字符串,就像用 exec() 方法一樣。

exec()test() 不同, String方法 search()、replace()match() 并不會用到 lastIndex 屬性。實際上, String 方法只是簡單地將 lastIndex 屬性值重置為0。如果讓一 個帶有修飾符 g 的正則表達式對多個字符串執(zhí)行 exec()test(),要么在每個字符串中 找出所有的匹配以便將 lastIndex 自動重置為零,要么顯式將 lastIndex 手動設(shè)置為 0(當(dāng)最后一次檢索失敗時需要手動設(shè)置 lastIndex )。

如果忘了手動設(shè)置 lastIndex 的值,那么下一次對新字符串進行檢索時,執(zhí)行檢索的起始位置可能就不是字符串的 開始位置,而可能是任意位置。當(dāng)然,如果RegExp不帶有修飾符g,則不必擔(dān)心會發(fā)生這種情況。同樣要記住,ECMAScript 5中,正則表達式直接量的每次計算都會創(chuàng)建一個新的 RegExp對象,每個新 RegExp對象 具有各自的 lastIndex屬性,這勢必會大大減少“殘留” lastIndex 對程序造成的意外影響。

參考

JavaScript 權(quán)威指南第六版

玩轉(zhuǎn)JavaScript正則表達式

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/84892.html

相關(guān)文章

  • JavaScript正則達式

    摘要:正則表達式的意義中的正則表達式使用表示,可以使用構(gòu)造函數(shù)來創(chuàng)建對象,不過對象更多的是通過一種特殊的直接量語法來創(chuàng)建。用構(gòu)造函數(shù)也可以定義一個與之等價的正則表達式,代碼如下正則表達式的模式規(guī)則是由一個字符序列組成的。 正則表達式的模式匹配 正則表達式(regular expression)是一個描述字符模式的對象。javascript的RegExp對象表示正則表達式,String和Reg...

    _Dreams 評論0 收藏0
  • JavaScript正則達式

    摘要:引用就是允許在同一個正則表達式的后部引用前面的子表達式。這個數(shù)字制定了帶圓括號的子表達式在正則表達式中的位置。對正則表達式中前一個子表達式的引用,并不是指對子表達式模式的引用,而是指與那個模式匹配的文本的引用。 前言 本文主要是在讀《JavaScript高級程序語言設(shè)計》一書有關(guān)正則表達式的章節(jié)的知識點記錄,方便后續(xù)查閱。 什么是正則表達式 正則表達式是用來描述字符組合的某種規(guī)則。它可...

    sixleaves 評論0 收藏0
  • JavaScript 闖關(guān)記》之正則達式

    摘要:正則表達式的字符串表示,按照字面量形式而非傳入構(gòu)造函數(shù)中的字符串模式返回。其中,表示匹配項在字符串中的位置,而表示應(yīng)用正則表達式的字符串。下面列出了正則表達式所不支持的特性。關(guān)卡按要求完成下列常用的正則表達式。 由于本課程的核心是 JavaScript,所以本文著重講解了「正則表達式」在 JavaScript 中的用法,并未深入「正則表達式」的具體細節(jié)。如果您尚不了解「正則表達式」,強...

    TalkingData 評論0 收藏0
  • JavaScript標(biāo)準(zhǔn)庫系列——RegExp對象(三)

    摘要:目錄導(dǎo)語理解正則表達式模式的規(guī)則字符串和正則實例的屬性和方法檢索實例小結(jié)導(dǎo)語正則表達式是處理字符串的一門藝術(shù)手法,應(yīng)用場景經(jīng)常出現(xiàn)在表單驗證部分高級程序設(shè)計一書開篇提到,這門語言最原始的應(yīng)用就是處理輸入驗證操作,所以正則表達式從誕生那一刻就 目錄 導(dǎo)語 1.理解正則表達式 2.模式的規(guī)則 3.字符串和正則實例的屬性和方法 4.檢索實例 5. 小結(jié) 導(dǎo)語 正則表達式是處理字符串的一門藝...

    邱勇 評論0 收藏0
  • JavaScript 正則達式使用

    摘要:當(dāng)正則表達式是靜態(tài)不變的,那么使用這種方式將會獲得更好的性能。使用正則表達式在中,正則表達式是通過對象的和方法以及字符串內(nèi)置的,,,方法使用的。這些標(biāo)志可以以任何順序單獨使用或一起使用,并作為正則表達式的一部分。 版權(quán)聲明:本文由吳仙杰創(chuàng)作整理,轉(zhuǎn)載請注明出處:https://segmentfault.com/a/1190000009169325 1. 引言 正則表達式本身語法是一致,...

    MyFaith 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<