摘要:說白了正則表達(dá)式就是處理字符串的我們可以用它來處理一些復(fù)雜的字符串。這個(gè)簡(jiǎn)單理解就是說字符出現(xiàn)的位置的右邊必須匹配到這個(gè)表達(dá)式。這個(gè)就是說字符出現(xiàn)的位置的前邊是這個(gè)表達(dá)式。
什么是正則表達(dá)式呢?
為什么要學(xué)習(xí)正則表達(dá)式正則表達(dá)式(regular expression)描述了一種字符串匹配的模式,可以用來檢查一個(gè)字符串是否含有某種子串、將匹配的子串做替換或者從某個(gè)字符串中取出符合某個(gè)條件的子串等。
說白了正則表達(dá)式就是處理字符串的,我們可以用它來處理一些復(fù)雜的字符串。
我們直接用一個(gè)例子來說明
//找出這個(gè)字符串中的所有數(shù)字 var str = "abc123de45fgh6789qqq111"; //方法1 function findNum(str) { var tmp = "", arr = []; for (var i = 0; i < str.length; i++) { var cur = str[i]; if (!isNaN(cur)) { tmp += cur; } else { if (tmp) { arr.push(tmp); tmp = ""; } } } if (tmp) { arr.push(tmp) } return arr; } console.log(findNum(str)) //["123", "45", "6789", "111"] //方法2 使用正則表達(dá)式 var reg = /d+/g; console.log(str.match(reg)) // ["123", "45", "6789", "111"]
通過比較2種方法我們明顯看出在對(duì)字符串進(jìn)行處理時(shí),使用正則表達(dá)式會(huì)簡(jiǎn)單許多,所以雖然正則表達(dá)式看起來像是火星文一樣的一堆亂碼的東西,但我們還是有必要去學(xué)習(xí)它的。
正則表達(dá)式的創(chuàng)建方式字面量創(chuàng)建方式
實(shí)例創(chuàng)建方式
var reg = /pattern/flags // 字面量創(chuàng)建方式 var reg = new RegExp(pattern,flags); //實(shí)例創(chuàng)建方式 pattern:正則表達(dá)式 flags:標(biāo)識(shí)(修飾符) 標(biāo)識(shí)主要包括: 1. i 忽略大小寫匹配 2. m 多行匹配,即在到達(dá)一行文本末尾時(shí)還會(huì)繼續(xù)尋常下一行中是否與正則匹配的項(xiàng) 3. g 全局匹配 模式應(yīng)用于所有字符串,而非在找到第一個(gè)匹配項(xiàng)時(shí)停止
字面量創(chuàng)建方式和構(gòu)造函數(shù)創(chuàng)建方式的區(qū)別
字面量創(chuàng)建方式不能進(jìn)行字符串拼接,實(shí)例創(chuàng)建方式可以
var regParam = "cm"; var reg1 = new RegExp(regParam+"1"); var reg2 = /regParam/; console.log(reg1); // /cm1/ console.log(reg2); // /regParam/
字面量創(chuàng)建方式特殊含義的字符不需要轉(zhuǎn)義,實(shí)例創(chuàng)建方式需要轉(zhuǎn)義
var reg1 = new RegExp("d"); // /d/ var reg2 = new RegExp("d") // /d/ var reg3 = /d/; // /d/元字符
代表特殊含義的元字符
d : 0-9之間的任意一個(gè)數(shù)字 d只占一個(gè)位置 w : 數(shù)字,字母 ,下劃線 0-9 a-z A-Z _ s : 空格或者空白等 D : 除了d W : 除了w S : 除了s . : 除了 之外的任意一個(gè)字符 : 轉(zhuǎn)義字符 | : 或者 () : 分組 : 匹配換行符 : 匹配邊界 字符串的開頭和結(jié)尾 空格的兩邊都是邊界 => 不占用字符串位數(shù) ^ : 限定開始位置 => 本身不占位置 $ : 限定結(jié)束位置 => 本身不占位置 [a-z] : 任意字母 []中的表示任意一個(gè)都可以 [^a-z] : 非字母 []中^代表除了 [abc] : abc三個(gè)字母中的任何一個(gè) [^abc]除了這三個(gè)字母中的任何一個(gè)字符
代表次數(shù)的量詞元字符
* : 0到多個(gè) + : 1到多個(gè) ? : 0次或1次 可有可無 {n} : 正好n次; {n,} : n到多次 {n,m} : n次到m次
量詞出現(xiàn)在元字符后面 如d+,限定出現(xiàn)在前面的元字符的次數(shù)
var str = "1223334444"; var reg = /d{2}/g; var res = str.match(reg); console.log(res) //["12", "23", "33", "44", "44"] var str =" 我是空格君 "; var reg = /^s+|s+$/g; //匹配開頭結(jié)尾空格 var res = str.replace(reg,""); console.log("("+res+")") //(我是空格君)
正則中的()和[]和重復(fù)子項(xiàng) //拿出來多帶帶說一下
**一般[]中的字符沒有特殊含義 如+就表示+
但是像w這樣的還是有特殊含義的**
var str1 = "abc"; var str2 = "dbc"; var str3 = ".bc"; var reg = /[ab.]bc/; //此時(shí)的.就表示. reg.test(str1) //true reg.test(str2) //false reg.test(str3) //true
[]中,不會(huì)出現(xiàn)兩位數(shù)
[12]表示1或者2 不過[0-9]這樣的表示0到9 [a-z]表示a到z 例如:匹配從18到65年齡段所有的人 var reg = /[18-65]/; // 這樣寫對(duì)么 reg.test("50") //Uncaught SyntaxError: Invalid regular expression: /[18-65]/: Range out of order in character class //聰明的你想可能是8-6這里不對(duì),于是改成[16-85]似乎可以匹配16到85的年齡段的,但實(shí)際上發(fā)現(xiàn)這也是不靠譜的 實(shí)際上我們匹配這個(gè)18-65年齡段的正則我們要拆開來匹配 我們拆成3部分來匹配 18-19 20-59 60-65 reg = /(18|19)|([2-5]d)|(6[0-5])/;
()的提高優(yōu)先級(jí)功能:凡是有|出現(xiàn)的時(shí)候,我們一定要注意是否有必要加上()來提高優(yōu)先級(jí);
()的分組 重復(fù)子項(xiàng) (兩個(gè)放到一起說)
分組: 只要正則中出現(xiàn)了小括號(hào)那么就會(huì)形成一份分組 只要有分組,exec(match)和replace中的結(jié)果就會(huì)發(fā)生改變(后邊的正則方法中再說) 分組的引用(重復(fù)子項(xiàng)) : 只要在正則中出現(xiàn)了括號(hào)就會(huì)形成一個(gè)分組,我們可以通過 (n是數(shù)字代表的是第幾個(gè)分組)來引用這個(gè)分組,第一個(gè)小分組我們可以用1來表示 例如:求出這個(gè)字符串"abAAbcBCCccdaACBDDabcccffffddaab"中出現(xiàn)最多的字母,并求出出現(xiàn)多少次(忽略大小寫)。 var str = "abbbbAAbcBCCccdaACBDDabcccffffddaab"; str = str.toLowerCase().split("").sort(function(a,b){return a.localeCompare(b)}).join(""); var reg = /(w)1+/ig; var maxStr = ""; var maxLen = 0; str.replace(reg,function($0,$1){ var regLen = $0.length; if(regLen>maxLen){ maxLen = regLen; maxStr = $1; }else if(maxLen == regLen){ maxStr += $1; } }) console.log(`出現(xiàn)最多的字母是${maxStr},共出現(xiàn)了${maxLen}次`)
當(dāng)我們加()只是為了提高優(yōu)先級(jí)而不想捕獲小分組時(shí),可以在()中加?:來取消分組的捕獲
var str = "aaabbb"; var reg = /(a+)(?:b+)/; var res =reg.exec(str); console.log(res) //["aaabbb", "aaa", index: 0, input: "aaabbb"] //只捕獲第一個(gè)小分組的內(nèi)容正則運(yùn)算符的優(yōu)先級(jí)
正則表達(dá)式從左到右進(jìn)行計(jì)算,并遵循優(yōu)先級(jí)順序,這與算術(shù)表達(dá)式非常類似。
相同優(yōu)先級(jí)的會(huì)從左到右進(jìn)行運(yùn)算,不同優(yōu)先級(jí)的運(yùn)算先高后低。
下面是常見的運(yùn)算符的優(yōu)先級(jí)排列 依次從最高到最低說明各種正則表達(dá)式運(yùn)算符的優(yōu)先級(jí)順序: : 轉(zhuǎn)義符 (), (?:), (?=), [] => 圓括號(hào)和方括號(hào) *, +, ?, {n}, {n,}, {n,m} => 量詞限定符 ^, $, 任何元字符、任何字符 | => 替換,"或"操作 字符具有高于替換運(yùn)算符的優(yōu)先級(jí),一般用 | 的時(shí)候,為了提高 | 的優(yōu)先級(jí),我們常用()來提高優(yōu)先級(jí) 如: 匹配 food或者foot的時(shí)候 reg = /foo(t|d)/ 這樣來匹配正則的特性
貪婪性
所謂的貪婪性就是正則在捕獲時(shí),每一次會(huì)盡可能多的去捕獲符合條件的內(nèi)容。
如果我們想盡可能的少的去捕獲符合條件的字符串的話,可以在量詞元字符后加?
懶惰性
懶惰性則是正則在成功捕獲一次后不管后邊的字符串有沒有符合條件的都不再捕獲。
如果想捕獲目標(biāo)中所有符合條件的字符串的話,我們可以用標(biāo)識(shí)符g來標(biāo)明是全局捕獲
var str = "123aaa456"; var reg = /d+/; //只捕獲一次,一次盡可能多的捕獲 var res = str.match(reg) console.log(res) // ["123", index: 0, input: "123aaa456"] reg = /d+?/g; //解決貪婪性、懶惰性 res = str.match(reg) console.log(res) // ["1", "2", "3", "4", "5", "6"]和正則相關(guān)的一些方法
這里我們只介紹test、exec、match和replace這四個(gè)方法
reg.test(str) 用來驗(yàn)證字符串是否符合正則 符合返回true 否則返回false
var str = "abc"; var reg = /w+/; console.log(reg.test(str)); //true
reg.exec() 用來捕獲符合規(guī)則的字符串
var str = "abc123cba456aaa789"; var reg = /d+/; console.log(reg.exec(str)) // ["123", index: 3, input: "abc123cba456aaa789"]; console.log(reg.lastIndex) // lastIndex : 0 reg.exec捕獲的數(shù)組中 // [0:"123",index:3,input:"abc123cba456aaa789"] 0:"123" 表示我們捕獲到的字符串 index:3 表示捕獲開始位置的索引 input 表示原有的字符串
當(dāng)我們用exec進(jìn)行捕獲時(shí),如果正則沒有加"g"標(biāo)識(shí)符,則exec捕獲的每次都是同一個(gè),當(dāng)正則中有"g"標(biāo)識(shí)符時(shí) 捕獲的結(jié)果就不一樣了,我們還是來看剛剛的例子
var str = "abc123cba456aaa789"; var reg = /d+/g; //此時(shí)加了標(biāo)識(shí)符g console.log(reg.lastIndex) // lastIndex : 0 console.log(reg.exec(str)) // ["123", index: 3, input: "abc123cba456aaa789"] console.log(reg.lastIndex) // lastIndex : 6 console.log(reg.exec(str)) // ["456", index: 9, input: "abc123cba456aaa789"] console.log(reg.lastIndex) // lastIndex : 12 console.log(reg.exec(str)) // ["789", index: 15, input: "abc123cba456aaa789"] console.log(reg.lastIndex) // lastIndex : 18 console.log(reg.exec(str)) // null console.log(reg.lastIndex) // lastIndex : 0 每次調(diào)用exec方法時(shí),捕獲到的字符串都不相同 lastIndex :這個(gè)屬性記錄的就是下一次捕獲從哪個(gè)索引開始。 當(dāng)未開始捕獲時(shí),這個(gè)值為0。 如果當(dāng)前次捕獲結(jié)果為null。那么lastIndex的值會(huì)被修改為0.下次從頭開始捕獲。 而且這個(gè)lastIndex屬性還支持人為賦值。
exec的捕獲還受分組()的影響
var str = "2017-01-05"; var reg = /-(d+)/g // ["-01", "01", index: 4, input: "2017-01-05"] "-01" : 正則捕獲到的內(nèi)容 "01" : 捕獲到的字符串中的小分組中的內(nèi)容
str.match(reg) 如果匹配成功,就返回匹配成功的數(shù)組,如果匹配不成功,就返回null
//match和exec的用法差不多 var str = "abc123cba456aaa789"; var reg = /d+/; console.log(reg.exec(str)); //["123", index: 3, input: "abc123cba456aaa789"] console.log(str.match(reg)); //["123", index: 3, input: "abc123cba456aaa789"]
上邊兩個(gè)方法console的結(jié)果有什么不同呢?二個(gè)字符串是一樣滴。
當(dāng)我們進(jìn)行全局匹配時(shí),二者的不同就會(huì)顯現(xiàn)出來了.
var str = "abc123cba456aaa789"; var reg = /d+/g; console.log(reg.exec(str)); // ["123", index: 3, input: "abc123cba456aaa789"] console.log(str.match(reg)); // ["123", "456", "789"]
當(dāng)全局匹配時(shí),match方法會(huì)一次性把符合匹配條件的字符串全部捕獲到數(shù)組中,
如果想用exec來達(dá)到同樣的效果需要執(zhí)行多次exec方法。
我們可以嘗試著用exec來簡(jiǎn)單模擬下match方法的實(shí)現(xiàn)。
String.prototype.myMatch = function (reg) { var arr = []; var res = reg.exec(this); if (reg.global) { while (res) { arr.push(res[0]); res = reg.exec(this) } }else{ arr.push(res[0]); } return arr; } var str = "abc123cba456aaa789"; var reg = /d+/; console.log(str.myMatch(reg)) // ["123"] var str = "abc123cba456aaa789"; var reg = /d+/g; console.log(str.myMatch(reg)) // ["123", "456", "789"]
此外,match和exec都可以受到分組()的影響,不過match只在沒有標(biāo)識(shí)符g的情況下才顯示小分組的內(nèi)容,如果有全局g,則match會(huì)一次性全部捕獲放到數(shù)組中
var str = "abc"; var reg = /(a)(b)(c)/; console.log( str.match(reg) ); // ["abc", "a", "b", "c", index: 0, input: "abc"] console.log( reg.exec(str) ); // ["abc", "a", "b", "c", index: 0, input: "abc"] 當(dāng)有全局g的情況下 var str = "abc"; var reg = /(a)(b)(c)/g; console.log( str.match(reg) ); // ["abc"] console.log( reg.exec(str) ); // ["abc", "a", "b", "c", index: 0, input: "abc"]
str.replace() 這個(gè)方法大家肯定不陌生,現(xiàn)在我們要說的就是和這個(gè)方法和正則相關(guān)的東西了。
正則去匹配字符串,匹配成功的字符去替換成新的字符串 寫法:str.replace(reg,newStr); var str = "a111bc222de"; var res = str.replace(/d/g,"Q") console.log(res) // "aQQQbcQQQde" replace的第二個(gè)參數(shù)也可以是一個(gè)函數(shù) str.replace(reg,fn); var str = "2017-01-06"; str = str.replace(/-d+/g,function(){ console.log(arguments) }) 控制臺(tái)打印結(jié)果: ["-01", 4, "2017-01-06"] ["-06", 7, "2017-01-06"] "2017undefinedundefined" 從打印結(jié)果我們發(fā)現(xiàn)每一次輸出的值似乎跟exec捕獲時(shí)很相似,既然與exec似乎很相似,那么似乎也可以打印出小分組中的內(nèi)容嘍 var str = "2017-01-06"; str = str.replace(/-(d+)/g,function(){ console.log(arguments) }) ["-01", "01", 4, "2017-01-06"] ["-06", "06", 7, "2017-01-06"] "2017undefinedundefined" 從結(jié)果看來我們的猜測(cè)沒問題。 此外,我們需要注意的是,如果我們需要替換replace中正則找到的字符串,函數(shù)中需要一個(gè)返回值去替換正則捕獲的內(nèi)容。
通過replace方法獲取url中的參數(shù)的方法
(function(pro){ function queryString(){ var obj = {}, reg = /([^?+]+)=([^?+]+)/g; this.replace(reg,function($0,$1,$2){ obj[$1] = $2; }) return obj; } pro.queryString = queryString; }(String.prototype)); // 例如 url為 https://www.baidu.com?a=1&b=2 // window.location.href.queryString(); // {a:1,b:2}零寬斷言
用于查找在某些內(nèi)容(但并不包括這些內(nèi)容)之前或之后的東西,如b,^,$那樣用于指定一個(gè)位置,這個(gè)位置應(yīng)該滿足一定的條件(即斷言),因此它們也被稱為零寬斷言。
在使用正則表達(dá)式時(shí),捕獲的內(nèi)容前后必須是特定的內(nèi)容,而我們又不想捕獲這些特定內(nèi)容的時(shí)候,零寬斷言就可以派上用場(chǎng)了。
零寬度正預(yù)測(cè)先行斷言 (?=exp)
零寬度負(fù)預(yù)測(cè)先行斷言 (?!exp)
零寬度正回顧后發(fā)斷言 (?<=exp)
零寬度負(fù)回顧后發(fā)斷言 (?
這四胞胎看著名字好長(zhǎng),給人一種好復(fù)雜好難的感覺,我們還是挨個(gè)來看看它們究竟是干什么的吧。
(?=exp) 這個(gè)簡(jiǎn)單理解就是說字符出現(xiàn)的位置的右邊必須匹配到exp這個(gè)表達(dá)式。
var str = "i"m singing and dancing"; var reg = /(w+(?=ing))/g var res = str.match(reg); console.log(res) // ["sing", "danc"] 注意一點(diǎn),這里說到的是位置,不是字符。 var str = "abc"; var reg = /a(?=b)c/; console.log(res.test(str)); // false // 這個(gè)看起來似乎是正確的,實(shí)際上結(jié)果是false reg中a(?=b)匹配字符串"abc" 字符串a(chǎn)的右邊是b這個(gè)匹配沒問題,接下來reg中a(?=b)后邊的c匹配字符串時(shí)是從字符串"abc"中a的后邊b的前邊的這個(gè)位置開始匹配的, 這個(gè)相當(dāng)于/ac/匹配"abc",顯然結(jié)果是false了
(?!exp) 這個(gè)就是說字符出現(xiàn)的位置的右邊不能是exp這個(gè)表達(dá)式。
var str = "nodejs"; var reg = /node(?!js)/; console.log(reg.test(str)) // false
(?<=exp) 這個(gè)就是說字符出現(xiàn)的位置的前邊是exp這個(gè)表達(dá)式。
var str = "¥998$888"; var reg = /(?<=$)d+/; console.log(reg.exec(str)) //888
(?位置的前邊不能是exp這個(gè)表達(dá)式。
var str = "¥998$888"; var reg = /(?最后,來一張思維導(dǎo)圖
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/81418.html
摘要:舉例一使用這個(gè)正則,打印結(jié)果為使用這個(gè)正則,打印結(jié)果為舉例二打印結(jié)果如下過濾標(biāo)簽?zāi)愫妹利惖纳虾O朕D(zhuǎn)化成你好,美麗的上海如果后面加,就會(huì)進(jìn)入非貪婪模式。如果后面不加,就會(huì)進(jìn)入貪婪模式,結(jié)果為上海。你好美麗的上海。 1.創(chuàng)建一個(gè)正則表達(dá)式 方法一:使用一個(gè)正則表達(dá)式字面量,其由包含在斜杠之間的模式組成。 var reg1 = /a/; var reg2 = /ab+c/; 方法二:調(diào)用Re...
摘要:舉例一使用這個(gè)正則,打印結(jié)果為使用這個(gè)正則,打印結(jié)果為舉例二打印結(jié)果如下過濾標(biāo)簽?zāi)愫妹利惖纳虾O朕D(zhuǎn)化成你好,美麗的上海如果后面加,就會(huì)進(jìn)入非貪婪模式。如果后面不加,就會(huì)進(jìn)入貪婪模式,結(jié)果為上海。你好美麗的上海。 1.創(chuàng)建一個(gè)正則表達(dá)式 方法一:使用一個(gè)正則表達(dá)式字面量,其由包含在斜杠之間的模式組成。 var reg1 = /a/; var reg2 = /ab+c/; 方法二:調(diào)用Re...
摘要:舉例一使用這個(gè)正則,打印結(jié)果為使用這個(gè)正則,打印結(jié)果為舉例二打印結(jié)果如下過濾標(biāo)簽?zāi)愫妹利惖纳虾O朕D(zhuǎn)化成你好,美麗的上海如果后面加,就會(huì)進(jìn)入非貪婪模式。如果后面不加,就會(huì)進(jìn)入貪婪模式,結(jié)果為上海。你好美麗的上海。 1.創(chuàng)建一個(gè)正則表達(dá)式 方法一:使用一個(gè)正則表達(dá)式字面量,其由包含在斜杠之間的模式組成。 var reg1 = /a/; var reg2 = /ab+c/; 方法二:調(diào)用Re...
摘要:對(duì)于含有量詞正則表達(dá)式,量詞是貪婪模式,會(huì)優(yōu)先選擇盡可能多的匹配修飾的字符,所以該表達(dá)式會(huì)優(yōu)先選擇匹配一個(gè)字符,當(dāng)匹配不到時(shí)再選擇不匹配字符。 正則表達(dá)式的語法 普通字符 字母、數(shù)字、漢字、下劃線以及一些沒有特殊定義的標(biāo)點(diǎn)符號(hào),都屬于普通字符,正則表達(dá)式中的普通字符匹配字符本身,如: var str = abced console.log(str.match(/a/)) // [a,...
摘要:一前言正則表達(dá)式入門實(shí)踐系列文章適合熟悉至少使用過正則表達(dá)式的同學(xué),在文章開始的時(shí)候我們都會(huì)帶著問題去思考如何正確應(yīng)用正則表達(dá)式解決出現(xiàn)的問題,在解決問題的過程中增長(zhǎng)你的知識(shí),提高你的實(shí)踐能力。 一 前言 正則表達(dá)式入門實(shí)踐系列文章適合熟悉至少使用過正則表達(dá)式的同學(xué),在文章開始的時(shí)候我們都會(huì)帶著問題去思考如何正確應(yīng)用正則表達(dá)式解決出現(xiàn)的問題,在解決問題的過程中增長(zhǎng)你的知識(shí),提高你的實(shí)踐...
摘要:系列種優(yōu)化頁面加載速度的方法隨筆分類中個(gè)最重要的技術(shù)點(diǎn)常用整理網(wǎng)頁性能管理詳解離線緩存簡(jiǎn)介系列編寫高性能有趣的原生數(shù)組函數(shù)數(shù)據(jù)訪問性能優(yōu)化方案實(shí)現(xiàn)的大排序算法一怪對(duì)象常用方法函數(shù)收集數(shù)組的操作面向?qū)ο蠛驮屠^承中關(guān)鍵詞的優(yōu)雅解釋淺談系列 H5系列 10種優(yōu)化頁面加載速度的方法 隨筆分類 - HTML5 HTML5中40個(gè)最重要的技術(shù)點(diǎn) 常用meta整理 網(wǎng)頁性能管理詳解 HTML5 ...
閱讀 1877·2021-11-19 09:40
閱讀 2594·2021-08-30 09:46
閱讀 2177·2021-08-03 14:01
閱讀 2648·2019-08-30 10:54
閱讀 1197·2019-08-29 16:38
閱讀 1440·2019-08-29 11:02
閱讀 2536·2019-08-28 18:16
閱讀 1679·2019-08-28 18:09