摘要:的正則表達式體系是參照建立的。字面量形式構造函數形式以上都是創(chuàng)建了一個內容為的正則表達式,其表示對一個手機號碼的校驗。按照給定的正則表達式進行替換,返回替換后的字符串。
正則表達式,也稱規(guī)則表達式,經常使用其來完成對字符串的校驗和過濾。由于正則表達式的靈活性、邏輯性和功能性都非常強大,而且 可以利用很簡單的方式完成對復雜字符串的控制,所以很多程序語言都支持正則表達式。在JavaScript中正則表示也非常強大和實用。
基本形式正則表達式(regular expression)是一種表達文本模式(即字符串結構)的方法,有點像字符串的模板,常常用作按照“給定模式”匹配文本的工具。比如,正則表達式給出一個Email地址的模式,然后用它來確定一個字符串是否為Email地址。JavaScript的正則表達式體系是參照Perl 5建立的。
新建正則表達式有兩種方法。一種是使用字面量,以斜杠表示開始和結束。
// 字面量形式 var telRegex1 = /^1[3|5|7|8]d{9}$/; // 構造函數形式 var telRegex2 = new RegExp("^1[3|5|7|8]d{9}$");
以上都是創(chuàng)建了一個內容為^1[3|5|7|8]d{9}$的正則表達式,其表示對一個手機號碼的校驗。必須以1開始,第二位為3/5/7/8,之后為9位數字。
這兩種寫法——字面量和構造函數——在運行時有一個細微的區(qū)別。采用字面量的寫法,正則對象在代碼載入時(即編譯時)生成;采用構造函數的方法,正則對象在代碼運行時生成。考慮到書寫的便利和直觀,實際應用中,基本上都采用字面量的寫法。
有一點需要注意,使用構造函數創(chuàng)建正則表達式時,傳入的參數是字符串形式的,在字符串內部,本身也是一個轉義符,因此需要再使用一個來對其進行正則表達式的轉義。上面第二個示例中,d才能代表任意數字。
關于正則表達式中,各種符號的含義,以及使用方法,請看后面的介紹:
元字符一些常用的元字符如下:
. 匹配除換行符之外的任意字符
w 匹配字母或數字或下劃線或漢字
s 匹配任意的空白符
d 匹配數字
匹配單詞的開始或結束
^ 匹配字符串的開始處
$ 匹配字符串的結束處。
* 匹配前面的子表達式任意次。
? 匹配前面子表達式0次或一次,等價于{0, 1}。
+ 匹配之前子表達式一次到多次,等價于{1, }。
{n} 匹配之前的子表達式n次。
{m,n} 匹配之前的子表達式最少m次,最多n次。
{n, } 匹配之前的子表達式至少n次。
[xyz] 字符集合,表示其中任意一個字符。表示范圍可用-鏈接,例如[a-z] 表示a-z之間的任意一個字母。還可以這樣書寫[A-Za-z0-9]。
[^xyz] 字符即可,表示非其中任意一個字符。表示范圍可用-鏈接,例如[^a-z] 表示非 a-z之間的任意一個字母。
| 表示或(or)關系,例如 com|cn,表示匹配com或者cn。
() 用于分組,其分組中的內容可已通過$1-$9按順序獲取(字符串相關方法中),之后的正則中也可以通過1-9進行引用(正則表達式內部)。(分組0表示整個正則匹配內容或整個正則表達式)
在正則表達式中,以上這些以及一些未列出的元字符都是有自身含義的,如果我們需要匹配這些元字符本身,可以使用對其進行轉義即可。
更多元字符可以查看:正則表達式
屬性 修飾符ignoreCase:返回一個布爾值,表示是否設置了i修飾符,該屬性只讀。
global:返回一個布爾值,表示是否設置了g修飾符,該屬性只讀。
multiline:返回一個布爾值,表示是否設置了m修飾符,該屬性只讀。
sticky:ES6返回一個布爾值,表示是否設置了y修飾符,只讀。
var r = /abc/igm; r.ignoreCase; // true r.global; // true r.multiline; // true匹配時屬性
lastIndex:返回下一次開始搜索的位置。該屬性可讀寫,但是只在設置了g修飾符時有意義。
source:ES5返回正則表達式的字符串形式(不包括反斜杠),該屬性只讀。
flags:ES6返回正則表達式中的修飾符。
var r = /abc/igm; r.lastIndex; // 0 r.source; // "abc" r.flags; //"igm"方法 test()
正則對象的test對象接收一個字符串,表示測試字符串,返回一個布爾值,表示是此字符串是否滿足匹配條件。
telRegex1.test("13612341234"); // true telRegex2.test("13612341234"); // true telRegex1.test("136123412"); // false
如果正則表達式帶有g修飾符,則每一次test方法都從上一次結束的位置開始向后匹配。同時,可以通過正則對象的lastIndex屬性指定開始搜索的位置。
var xReg = /x/g; var str = "xyz_x1_y1_x3"; xReg.lastIndex; // 0 xReg.test(str); // true xReg.lastIndex; // 1 xReg.test(str); // true xReg.lastIndex; // 5 // 指定位置開始 指定下次匹配從最后一位開始,就匹配不到了 xReg.lastIndex = 11; // 11 xReg.test(str); // false xReg.lastIndex; // 0
var indexReg = /^(?:http|https).+/jwebui/pages/themes/(w+)/1.jspx(?S+)?$/i ;
上面是一個F8中檢查是否為首頁的正則表達式。
最開始的^ 和最后的$分別表示匹配的開始和結束。
(?:http|https)表示兩者之一,這么寫是非獲取的組匹配,()不會被分組存儲。也可以寫成(http|https) 但是后面的1就需要替換成2了,因為這么寫時此處形成了第一個分組。
.+ 就是任意字符至少出現一次。
/jwebui/pages/themes/ 就是匹配字符串"/jwebui/pages/themes/"。
(w+) 作為第一個分組,表示任意字母或數字或下劃線或漢字至少出現一次。
1表示對第一個分組的引用,再重復第一分組的內容 。
.jspx 表示.jspx。
(?S+)? 表示(?S+) 匹配的內容出現0次或一次。其中:
? 表示? 。
S+ 表示任意可見字符出現至少一次。
`
正則對象的exec方法,可以返回匹配結果。如果發(fā)現匹配,就返回一個數組,成員是每一個匹配成功的子字符串,否則返回null。
如果正則表示式包含圓括號(即含有“組匹配”),則返回的數組會包括多個成員。第一個成員是整個匹配成功的結果,后面的成員就是圓括號對應的匹配成功的組。也就是說,第二個成員對應第一個括號,第三個成員對應第二個括號,以此類推。整個數組的length屬性等于組匹配的數量再加1。
var ipReg = /(d{1,3}.){3}(d{1,3})/; var ipStr = "My ip is "192.168.118.47" , please tell me yours"; ipReg.exec(ipStr); // ["192.168.118.47", "118.", "47"]
上面第一段代碼表示一個簡單的IP檢驗,數字的1-3位之后緊跟一個.,接著這個整體要出現3次,最后再有一段數字的1-3位。結果數組中,第一個值表示匹配到的結果,之后的表示正則分組匹配到的內容。
如果正則表達式加上g修飾符,則可以使用多次exec方法,下一次搜索的位置從上一次匹配成功結束的位置開始。同時還可以指定lastIndex,使之下次從指定位置開始(可見之前的test示例)。
var ipLastReg = /d+(?=;)/g; var ipsStr = "192.168.118.47;192.168.118.46;192.168.118.48;"; ipLastReg.exec(ipsStr); // ["47"] ipLastReg.exec(ipsStr); // ["46"] ipLastReg.exec(ipsStr); // ["48"]
上面代碼中正則中的(?=;)表示先行斷言,表示只匹配在;前面d+。
字符串相關方法如果只是為了得到是否匹配,請使用 RegExp.test()方法或字符串實例的.search() 替代,效率更高。
之所以稱之為字符串相關方法是因為其是在字符串上調用的(雖然ES6開始,內部調用的是正則上的方法,但還是在字符串上提供的入口)。
match():返回一個數組,成員是所有匹配的子字符串。
search():按照給定的正則表達式進行搜索,返回一個整數,表示匹配開始的位置。
replace():按照給定的正則表達式進行替換,返回替換后的字符串。
split():按照給定規(guī)則進行字符串分割,返回一個數組,包含分割后的各個成員。
match()match方法對字符串進行正則匹配,返回匹配結果。此方法方法與正則對象的exec方法非常類似:匹配成功返回一個數組,匹配失敗返回null。如果正則表達式帶有g修飾符,則該方法與正則對象的exec方法行為不同,會一次性返回所有匹配成功的結果。
var ipLastReg = /d+(?=;)/g; var ipsStr = "192.168.118.47;192.168.118.46;192.168.118.48;"; ipsStr.match(ipLastReg); // ["47", "46", "48"]
上面的正則是匹配IP中的最后一位,其中使用了(?=;)意為先行斷言,表示只匹配在;之前的內容,但是不包括;。關于更多先行斷言,請看下文。
search()search方法,返回第一個滿足條件的匹配結果(可直接使用字符串,不一定是正則對象)在整個字符串中的位置。如果沒有任何匹配,則返回-1。
var nowDateStr = "2016-11-1"; var testReg = /-/g; nowDateStr.search(testReg); // 4 // 再次查找還是4 nowDateStr.search(testReg); // 4 // 檢查lastIndex 并設置 testReg.lastIndex; // 0 testReg.lastIndex = 6; nowDateStr.search(testReg); // 4 結果仍為4
replace()search方法總是從字符串的開始位置查找,與正則表達式的g修飾符和lastIndex屬性無關。
replace方法可以替換匹配的值,返回替換后的新字符串。它接受兩個參數,第一個是搜索模式(可直接使用字符串,不一定是正則對象),第二個是替換的內容(可使用字符串或一個函數)。搜索模式如果不加g修飾符,就替換第一個匹配成功的值,否則替換所有匹配成功的值。
其中replace方法的第二個參數可以使用美元符號$,用來指代所替換的內容,具體如下所示:
$& 指代匹配的子字符串。
$` 指代匹配結果前面的文本。
$" 指代匹配結果后面的文本。
$n 指代匹配成功的第n組內容,n是從1開始的自然數。
$$ 指代美元符號$。
var re = /-/g; var str = "2016-11-01"; var newstr = str.replace(re,"."); console.log(newstr); // "2016.11.01" "hello world".replace(/(w+)s(w+)/, "$2 $1"); // "world hello" "abc".replace("b", "[$`-$&-$"]"); // "a[a-b-c]c"
第二個參數為函數:
function toCamelStyle(str) { // 匹配-以及之后的一個字符,其中這個字符在一個分組內 var camelRegExp = /-([a-z])/ig; return str.replace(camelRegExp, function(all, letter) { // all為匹配到的內容,letter為組匹配 return letter.toUpperCase(); }); } toCamelStyle("margin-left"); // "marginLeft" toCamelStyle("aa-bb-cccc"); // "aaBbCccc"
以上代碼展示通過正則將aa-bb-cccc這樣的字符串轉化為aaBbCccc 這種形式。replace回調函數接收兩個參數,第一個為匹配到的內容,第二個為匹配到的分組,有多少組就可以傳多少個參數,在此之后還可以有兩個參數,一個為匹配到內容在原字符串的位置,另一個是原字符串。
split()split方法按照正則規(guī)則分割字符串,返回一個由分割后的各個部分組成的數組。該方法接受兩個參數,第一個參數是分隔規(guī)則(可直接使用字符串,不一定是正則對象),第二個參數是返回數組的最大成員數。
"2016-11-01".split("-"); // ["2016", "11", "01"] "2016-11-01".split(/-/); // ["2016", "11", "01"]貪婪模式和懶惰模式
當正則表達式中包含能接受重復的限定符時,通常的行為是(在使整個表達式能得到匹配的前提下)匹配盡可能多的字符,稱之為貪婪模式。
例如:
var s = "aaa"; s.match(/a+/); // ["aaa"]
有時,我們更需要懶惰匹配,也就是匹配盡可能少的字符。前面給出的限定符都可以被轉化為懶惰匹配模式,只要在它后面加上一個問號?。這樣.*?就意味著匹配任意數量的重復,但是在能使整個匹配成功的前提下使用最少的重復。
var s = "aaa"; s.match(/a+?/); // ["a"]
以下是一些說明
*? 重復任意次,但盡可能少重復
+? 重復1次或更多次,但盡可能少重復
?? 重復0次或1次,但盡可能少重復
{n,m}? 重復n到m次,但盡可能少重復
{n,}? 重復n次以上,但盡可能少重復
也就是說默認情況下,都是貪婪模式,加上一個?時就轉化為了懶惰模式,也稱非貪婪模式。
組匹配通常一個()中的內容就構成了一個分組,此分組內容將被存儲,可在之后的正則表達式(使用1-9)和相關方法中(使用 $1-$9)引用,前面已經介紹過了,就不再說了。
關于組匹配,還有以下幾種情況:
非捕獲組(?:x) 稱為非捕獲組(Non-capturing group),表示不返回該組匹配的內容,即匹配的結果中不計入這個括號。
// 正常匹配 var url = /(http|ftp)://([^/ ]+)(/[^ ]*)?/; url.exec("http://google.com/"); // ["http://google.com/", "http", "google.com", "/"] // 非捕獲組匹配 var url = /(?:http|ftp)://([^/ ]+)(/[^ ]*)?/; url.exec("http://google.com/"); // ["http://google.com/", "google.com", "/"]
先行斷言之后先行斷言和先行否定斷言也都是非捕獲組
x(?=y)稱為先行斷言(Positive look-ahead),x只有在y前面才匹配,y不會被計入返回結果。
比如之前匹配ip的例子:
var ipLastReg = /d+(?=;)/g; var ipsStr = "192.168.118.47;192.168.118.46;192.168.118.48;"; ipsStr.match(ipLastReg); // ["47", "46", "48"]
上面正則對象中(?=;)就表示只匹配在;之前的內容,但是不包括;。
先行否定斷言x(?!y)稱為先行否定斷言(Negative look-ahead),x只有不在y前面才匹配,y不會被計入返回結果。
var xreg = /d+(?!%)/g ; xreg.exec("100% is 1"); // ["10"] xreg.exec("100% is 1"); // ["1"] /d+?(?!%)/.exec("100% is 1"); // ["1"]
上面代碼表示匹配不在%前的數字,xreg中直接書寫的d+ 表示貪婪模式,因此第一次匹配到的是10,第二次才會匹配到后面的1,因為作為數字10本身也不在%前面,正則不會將100當成一個整體(注意:這里需要定義一個正則對象來調用,直接以字面量形式的正則調用時,每次調用都是一個新對象,結果始終是10)。
為了一次匹配到最后的1,我們在d+之后加一個?將其轉為非貪婪模式即可。
為了一次匹配到前面100中的1,我們在d+之后加一個?將其轉為非貪婪模式即可。
ES6擴展 構造函數ES6之前,JavaScript中不支持后行斷言和否定后行斷言,ES6中添加了對此的支持,請看之后的ES擴展部分。
RegExp構造函數的參數有兩種情況。
第一種情況是,參數是字符串,這時第二個參數表示正則表達式的修飾符(flag)。
第二種情況是,參數是一個正則表示式,此時不能有第二個參數,會返回一個原有正則表達式的拷貝。
ES6 針對第二種情況,允許傳入第二個參數,用于設置第一個參數正則表達式的修飾符。
var regex = new RegExp(/xyz/, "i"); // ES6之前 語法錯誤 new RegExp(/abc/ig, "i"); // ES6中結果為: /abc/i字符串的正則方法
字符串對象共有4個方法,可以使用正則表達式:match()、replace()、search()和split()。
ES6將這4個方法,在語言內部全部調用RegExp的實例方法,從而做到所有與正則相關的方法,全都定義在RegExp對象上。
修飾符ES6對正則表達式添加了u修飾符,含義為“Unicode模式”,用來正確處理大于uFFFF的Unicode字符。也就是說,會正確處理四個字節(jié)的UTF-16編碼。
ES6還為正則表達式添加了y修飾符,叫做“粘連”(sticky)修飾符。
y修飾符的作用與g修飾符類似,也是全局匹配,后一次匹配都從上一次匹配成功的下一個位置開始。不同之處在于,g修飾符只要剩余位置中存在匹配就可,而y修飾符確保匹配必須從剩余的第一個位置開始,這也就是“粘連”的涵義。
var s = "aaa_aa_a"; var r1 = /a+/g; var r2 = /a+/y; // 第一次都能正確匹配 r1.exec(s); // ["aaa"] r2.exec(s); // ["aaa"] // 第二次結果就不一致了 r1.exec(s); // ["aa"] r2.exec(s); // null
個人理解,y是類似于在每次匹配時隱式地添加了^,表示開始位置。
屬性ES5中,正則對象存在source屬性,用于返回正則表達式本身。
ES6中,又添加了flags屬性,用于返回正則對象的所有修飾符。
后行斷言后行斷言于先行斷言相反。例如/(?<=y)x/ 表示匹配x,但是要求x必須在y后面。
同理 后行否定斷言則為:/(? 表示匹配x,但是要求x不能在y后面。
參考鏈接需要注意的是,存在后行斷言時,正則執(zhí)行順序發(fā)生了改變,會先匹配后行斷言的這部分,再匹配其他的的,順序變成了從右向左。因此一些匹配操作的結果可能大不一致,而且正則中的1-9的引用順序也會發(fā)生變化。
ES6入門 - 正則表達式
JavaScript RegExp
正則表達式30分鐘入門教程
原文發(fā)表在我的博客JavaScript正則表達式RegExp,歡迎訪問!
錯誤修正先行否定斷言中
為了一次匹配到最后的1,我們在d+之后加一個?將其轉為非貪婪模式即可。
為了一次匹配到前面100中的1,我們在d+之后加一個?將其轉為非貪婪模式即可。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/82169.html
摘要:選擇分組和引用正則表達式的語法還包括指定選擇項子表達式分組和引用前一子表達式的特殊字符。帶圓括號的表達式的另一個用途是允許在同一正則表達式的后部引用前面的子表達式。 正則表達式(regular expression)是一個描述字符模式的對象。JavaScript的 RegExp類 表示正則表達式,String和RegExp都定義了方法,后者使用正則表達式進 行強大的模式匹配和文本檢索與...
摘要:正則表達式的字符串表示,按照字面量形式而非傳入構造函數中的字符串模式返回。其中,表示匹配項在字符串中的位置,而表示應用正則表達式的字符串。下面列出了正則表達式所不支持的特性。關卡按要求完成下列常用的正則表達式。 由于本課程的核心是 JavaScript,所以本文著重講解了「正則表達式」在 JavaScript 中的用法,并未深入「正則表達式」的具體細節(jié)。如果您尚不了解「正則表達式」,強...
摘要:目錄導語理解正則表達式模式的規(guī)則字符串和正則實例的屬性和方法檢索實例小結導語正則表達式是處理字符串的一門藝術手法,應用場景經常出現在表單驗證部分高級程序設計一書開篇提到,這門語言最原始的應用就是處理輸入驗證操作,所以正則表達式從誕生那一刻就 目錄 導語 1.理解正則表達式 2.模式的規(guī)則 3.字符串和正則實例的屬性和方法 4.檢索實例 5. 小結 導語 正則表達式是處理字符串的一門藝...
摘要:由于某些字符類非常常用,的正則表達式中,使用特殊轉義字符表示他們。多行搜索代碼示例對象創(chuàng)建對象可以通過引用類型創(chuàng)建正則表達式對象參數參數被稱為模式,可以使任何簡單或復雜的正則表達式,包含字符類限定符分組向前查找以及反向引用等。 概述 正則表達式是什么 正則表達式(RegularExpression):由一些普通字符和特殊字符組成的,用以描述一種特定的字符規(guī)則的表達式。正則表達式常用在一...
Javascript的正則表達式是前端中比較重要的部分,正則表達式主要用于字符串處理,表單驗證等場合,實用高效,文章主要對JavaScript中的正則的學習與總結 正則表達式的定義 正則表達式:是一個描述字符模式的對象,JavaScrip中正則表達式用RegExp對象表示,可以使用RegExp構造函數來創(chuàng)建正則對象 正則表達式的創(chuàng)建 1.字面量創(chuàng)建 var reg = /[a-z]/; 2.構...
閱讀 1523·2023-04-26 02:03
閱讀 4706·2021-11-22 13:53
閱讀 4578·2021-09-09 11:40
閱讀 3781·2021-09-09 09:34
閱讀 2124·2019-08-30 13:18
閱讀 3500·2019-08-30 11:25
閱讀 3294·2019-08-26 14:06
閱讀 2544·2019-08-26 13:52