摘要:正則表達式是用于匹配字符串中字符組合的模式。在中,正則表達式也是對象。注意如果正則表達式設置了全局匹配標志,和的執行會改變正則表達式屬性。顯示顯示方法執行一個檢索,用來查看正則表達式與指定的字符串是否匹配。
正則表達式是用于匹配字符串中字符組合的模式。在 JavaScript中,正則表達式也是對象。正則表達式對象: 1、創建正則表達式的兩種形式 1.1、使用字面量來創建構造函數
這些模式被用于 RegExp 的 exec 和 test 方法, 以及 String 的 match、replace、search 和 split 方法。
一個正則表達式字面量,其由包含在斜杠之間的模式組成/pattern/flags
pattern: 正則表達式的文本。
flags: 正則表達式的標志
例如:全局查找含有hello字符的字符串,忽略字符的大小寫
var regexp = /hello/gi regexp.test(" Hello world") //true regexp.test("Say hEllo") //true1.2、使用構造函數來創建正則表達式
使用構造函數提供正則表達式的運行時編譯,如果你要動態生成一個正則表達式應該選用這種方式
new RegExp(pattern [, flags])
例如:
let regex = new RegExp("ab+c", "img");
構造函數可以接受正則表達式文本和字符串,作為第一個參數, 正則表達式標志作為第二個參數
let regex = new RegExp(/^[a-zA-Z]+[0-9]*W?_$/, "gi");
注意如果構造函數的第一個參數傳入的是字符串,它須要經過以下幾個步驟的處理:
1.去掉正則表達式文本兩頭的 /
2.正則表達式文本里面的所有 都要進行轉義寫成
let regex = new RegExp("^[a-zA-Z]+[0-9]*W?_$", "gi");
當我們要做一個很復雜的查找時,可以像下面這樣分解步驟
let str = "^&*()_ sdf7$df NN2、正則表達式對象的lastIndex屬性 lastIndex是正則表達式實例的一個讀/寫整數屬性,它指定從哪個索引開始下一個匹配。
The lastIndex is a read/write integer property of regular expression instances that specifies the index at which to start the next match.var regex1 = new RegExp( "ble", "g" ); var str1 = "table football, foosball"; var judage1 = regex1.test(str1); console.log(judage1); //true console.log(regex1.lastIndex); //5 var judage2 = regex1.test(str1); console.log(judage2); //false console.log(regex1.lastIndex); //0這里我們可以看到同一個全局檢索的正則表達式(含有g),執行多次后,檢索的內容竟然是不同的。judage1 為 true,judage2 為false。因為第一次檢索后lastIndex會被改變,指向它匹配字符所在處的最后一個索引+1。而之后再次調用正則檢索,正則會從上一次lastIndex停止的地方開始檢索。所以第一次匹配能夠匹配到“ble”,而第二次從上一次“ble”停下的地方開始檢索,后面沒有“ble”字符,所以judage2 = false。
?注意:
如果正則表達式設置了全局匹配標志g,test() 和 exec()的執行會改變正則表達式 lastIndex屬性。連續的執行test()方法,后續的執行將會從 lastIndex 處開始匹配字符串var regex1 = new RegExp( "ble", "g" ); var str1 = "table football, foosball"; console.log(regex1.test(str1)) //true console.log(regex1.test(str1)) //false因為多次調用設置了全局匹配標志g的test(), 會導致 regex1的lastIndex 屬性改變。所以千萬不要在for 循環里面調用含有全局匹配標志g的正則函數,那樣匹配驗證會出問題。
3、編寫一個正則表達式的模式 3.1、使用簡單的模式let regexp = /abc/; //直接匹配在一個字符串中,是否含有字符"abc" regexp.test("123abc @#$hh") //true3.2、使用特殊字符let regexp = /ab*c/ //* 是特殊字符,意思是前面一項出現了零個或者多個 regexp.test("123ac @#$hh") //true regexp.test("123abbbbbbbbbbc @#$hh") //true regexp.test("123abdc @#$hh") //false4、正則表達式有哪些特殊字符 4.1、簡單的特殊字符4.2、高級的特殊字符
字符 含義 是一個轉義字符
1.放在普通字符前面將后面的普通字符轉義成特殊字符
/d/是匹配一個字符d,而/d/ 就是匹配一個數字
2.放在特殊字符前面,將后面特殊字符轉化成普通字符
/A*/是匹配0個至多個A,/A*/就真的是匹配 "A*" 字符
3. 使用 new RegExp("pattern") 的時候不要忘記將 進行轉義,因為 在字符串里面也是一個轉義字符。
new RegExp("d")只匹配d字符,? ?new? RegExp("d")? 才會匹配數字^ 匹配輸入的開始。如果設置了多行標志m,那么也匹配換行符后緊跟的位置。
例如,/^A/ 并不會匹配 "an A" 中的 "A",但是會匹配 "An E" 中的 "A"。
/^w/m 并不會匹配 "Hello world"中的 "w", 也不會匹配 "Hellon world"(w前面有空格),但是會匹配 "Hello world"$ 匹配輸入的結束。如果設置了多行標志m,那么也匹配換行符前的位置。
例如,/t$/ 并不會匹配 "eater" 中的 "t",但是會匹配 "eat" 中的 "t"。* 匹配前一個字符0次或多次。等價于 {0,}。
例如,/bo*/會匹配 "A ghost boooooed" 中的 "booooo" 和 "A bird warbled" 中的 "b",但是在 "A goat grunted" 中將不會匹配任何東西。
注意/bo*/ 意思是以b字母開頭,后面有0個或多個o,而不是有0個或多個bo
*只針對離它最近的字符
/(bo)*/ 意思才是匹配0個或多個"bo". (小數點)匹配除換行符之外的任何單個字符。
例如,/.n/將會匹配 "nay, an apple is on the tree" 中的 "an" 和 "on",但是不會匹配 "nay",因為 "." 會將每條字符串的首部視作有一個換行符x|y 匹配‘x’或者‘y’。
例如,/green|red/匹配“green apple”中的‘green’和“red apple”中的‘red’{n} n是一個正整數,匹配了前面一個字符剛好發生了n次。
比如,/a{2}/不會匹配“candy”中的"a",但是會匹配“caandy”中所有的a,以及“caaandy”中的前兩個"a"。{n,m} n 和 m 都是整數。匹配前面的字符至少n次,最多m次。如果 n 或者 m 的值是0, 這個值被忽略。
例如,/a{1, 3}/ 并不匹配“cndy”中的任意字符,匹配“candy”中的a,匹配“caandy”中的前兩個a,也匹配“caaaaaaandy”中的前三個a。注意,當匹配”caaaaaaandy“時,匹配的值是“aaa”,即使原始的字符串中有更多的a。
注意:{n,m}之間沒有空格[xyz] 一個字符集合。匹配方括號中的任意字符,包括轉義序列。你可以使用破折號(-)來指定一個字符范圍。
對于點(.)和星號(*)這樣的特殊符號,如果不進行轉義,在一個字符集中沒有特殊的意義。
/[ad]/g 只會匹配“add 20190726”中的 ‘a’和‘d’,并不會匹配數字
如果進行了轉義
/[ad]/g 就會匹配“add 20190726”中的‘a’和所有數字[^xyz] 一個反向字符集。也就是說, 它匹配任何沒有包含在方括號中的字符。你可以使用破折號(-)來指定一個字符范圍。
使用方法同[xyz], 只是 [^xyz]是不包含
例如,[^abc] 和 [^a-c] 是一樣的。他們匹配"brisket"中的‘r’,也匹配“chop”中的‘h’。d 匹配一個數字。
等價于[0-9]。
例如, /d/ 或者 /[0-9]/ 匹配"B2 is the suite number."中的"2"。D 匹配一個非數字字符。
等價于[^0-9]。
例如, /D/ 或者 /[^0-9]/ 匹配"B2 is the suite number."中的"B"。w 匹配一個單字字符(字母、數字或者下劃線)。
等價于[A-Za-z0-9_]。
例如, /w/ 匹配 "apple," 中的 "a","$5.28,"中的 "5" 和 "3D." 中的 "3"。W 匹配一個非單字字符。
等價于[^A-Za-z0-9_]。
例如, /W/ 或者 /[^A-Za-z0-9_]/ 匹配 "50%." 中的 "%"更新中
正則表達式對象常用的3種方法: 1、RegExp.prototype.toString()RegExp 對象并沒有繼承 Object.prototype.toString(),而是覆蓋了 Object 對象的 toString() 方法,對于 RegExp 對象,toString 方法返回一個該正則表達式的字符串形式。
myExp = new RegExp("a+b+c"); console.log(myExp.toString()); // 顯示 "/a+b+c/" foo = new RegExp("bar", "g"); console.log(foo.toString()); // 顯示 "/bar/g"2、RegExp.prototype.test()test() 方法執行一個檢索,用來查看正則表達式與指定的字符串是否匹配。返回 true 或 false。
即一個字符串是否包含滿足這個正則表達式的子字符串let _regexp = new RegExp("Wo" , "i"); let str = "hello world!"; let result = _regexp.test(str); console.log(result); //true3、RegExp.prototype.exec()exec() 方法在一個指定字符串中執行一個搜索匹配。返回一個結果數組或 null。
如果匹配成功,exec() 方法返回一個數組,并更新正則表達式對象的屬性。返回的數組將完全匹配成功的文本作為第一項,將正則括號里匹配成功的作為數組填充到后面。var params = "user" var regexp = new RegExp("[?#&]" + params + "=([^]*)", "i") var str = "www.qq.com?user=Tom&psw=123456"; var res = regexp.exec(str); console.log(res) // ["?user=Tom", "Tom"]可以看到返回數組的第一個元素就是整個的匹配模式所匹配到的字符串,而第二個匹配到的字符恰好是參數值。這是exec匹配返回的規則:第一個元素為整個的匹配字符串,從第二個參數開始返回模式中每一個()自身正則所匹配的字符串。這里面([^]*)返回的就是不以&或#開頭的字符串,即等號后面對應的參數Tom。
然后我們給params 再加一個括號, 便把params(匹配到的)也輸出來了。
var params = "user" var regexp = new RegExp("[?#&]" + "(" +params+ ")" + "=([^]*)", "i") var str = "www.qq.com?user=Tom&psw=123456"; var res = regexp.exec(str); console.log(res) // ["?user=Tom", "user", "Tom"]String 對象使用正則的幾種方法 1、match方法match 方法檢索返回一個字符串匹配正則表達式的的結果。
當你不使用g標志,即不進行全局檢索時, 僅返回第一個完整匹配及其相關的捕獲組(Array)。let str = "……ssdf #$%^& ab Abbbbb ABC153**"; let regexp = new RegExp("ab", "i"); let result = str.match(regexp) console.log(result) 輸出: [ "ab", //第一個完整的匹配項 index: 13, //匹配結果的開始位置 input: "……ssdf #$%^& ab Abbbbb ABC153**", //搜索的字符串 groups: undefined //一個捕獲組數組 或 undefined(如果沒有定義命名捕獲組) ]如果match沒有匹配到任何項,則會直接返回null
let regexp2 = new RegExp("xxx", "i"); let result2 = str.match(regexp2) //null?注意match還有兩種特殊的使用情況:
1、match 如果傳入一個非正則表達式對象,則會隱式地使用 new RegExp(obj) 將其轉換為一個 RegExplet result3 = str.match("ab") //str.match("ab") = str.match(new RegExp("ab")); 輸出還是和之前一樣: [ "ab", index: 13, input: "……ssdf #$%^& ab Abbbbb ABC153**", groups: undefined ]2、如果你沒有給出任何參數并直接使用match() 方法 ,你將會得到一 個包含空字符串的 Array :[""] ,而不是null。
let result 4 = str.match() 輸出: [ "", index: 0, input: "……ssdf #$%^& ab Abbbbb ABC153**", groups: undefined ]2、replace方法通過正則查找到匹配項,然后替換這些字符,注意replace方法只會返回替換后的結果,不會改變原字符串。
使用示例:
1、直接替換字符串默認只會替換第一次匹配的項。let str = "……ssdf #$%^& ab Abbbbb ABC153**"; let result = str.replace("s", 77) console.log(result) //……77sdf #$%^& ab Abbbbb ABC153** 默認只會替換第一個s2、正則加g標志,全局替換所有匹配的字符
let str = "……ssdf #$%^& ab Abbbbb ABC153**"; let reg = /ab/gi let result = str.replace(reg, "T") console.log(result) //……ssdf #$%^& T Tbbbb TC153** 所有的ab都替換成了 T3、替換字符串支持插入下面的特殊變量名① $& 插入匹配的子串
let str = "劉一、陳二、張三、李四、王五、趙六、孫七、周八、吳九、鄭十" let reg = new RegExp("[張趙孫][三七八]", "gi") let result = str.replace(reg, "新名字") console.log(result) //劉一、陳二、新名字、李四、王五、趙六、新名字、周八、吳九、鄭十 let result2 = str.replace(reg, "新名字$&"); console.log(result2) //劉一、陳二、新名字張三、李四、王五、趙六、新名字孫七、周八、吳九、鄭十② $` 插入當前匹配的子串左邊的內容。
let result3 = str.replace(reg, "新名字$`"); console.log(result3) //劉一、陳二、新名字劉一、陳二、、李四、王五、趙六、新名字劉一、陳二、張三、李四、王五、趙六、、周八、吳九、鄭十③ $" 插入當前匹配子串右邊的內容
④ $n 插入第n個括號匹配的字符串
?注意:
new RexExp()第一個參數需要是一個含有正則的文本
n 是個小于100的非負整數
索引是從1開始(即插入第一個括號里面匹配的內容為 $1)
例子:var re = /(w+)s(w+)/; var str = "John Smith"; var newstr = str.replace(re, "$2, $1"); console.log(newstr); // Smith, John //分析第一個括號里面匹配到了John 即 $1是John,第二個括號里面匹配到了 Smith, 即$2 為Smith3、search方法如果匹配成功,則 search() 返回正則表達式在字符串中首次匹配項的索引;否則,返回 -1。
let str = "Hello AbC aBC ABC abc" let result = str.search(/abc/gi); console.log(result) //6 //注意即使你用了全局查找標志g,search也只會返回首次匹配的索引,索引走0開始4、Split 方法// split 方法默認搜素全局,所以不管你的正則是否使用了g標志,結果都一樣 let str = "Hello AbC aBC ABC abc" let result = str.split(/[a]/); let result2 = str.split(/[a]/g); console.log(result) //[ "Hello AbC ", "BC ABC ", "bc" ] console.log(result2) //[ "Hello AbC ", "BC ABC ", "bc" ] //split 可以限制分割幾塊字符串,當返回的分割字塊到達限制大小時分割停止 let result3 = str.split(/[a]/g, 2); console.log(result3) //[ "Hello AbC ", "BC ABC " ] //當分割的限制大于返回數組的長度時 let result3 = str.split(/[a]/g, 3000); console.log(result3) //[ "Hello AbC ", "BC ABC ", "bc" ]參考資料
MDN web docs 正則表達式
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/106146.html
摘要:為什么要避免阻塞事件循環和工作池使用少量線程來處理許多客戶端,在中有兩種類型的線程一個事件循環又稱主循環主線程事件線程等,以及一個工作池也稱為線程池中的個的池。 不要阻塞事件循環(或工作池) 你應該閱讀這本指南嗎? 如果你編寫的內容比簡短的命令行腳本更復雜,那么閱讀本文應該可以幫助你編寫性能更高、更安全的應用程序。 本文檔是在考慮Node服務器的情況下編寫的,但這些概念也適用于復雜的N...
摘要:一旦我們滿足了基本條件值為,我們將不再調用遞歸函數,只是有效地執行了。遞歸深諳函數式編程之精髓,最被廣泛引證的原因是,在調用棧中,遞歸把大部分顯式狀態跟蹤換為了隱式狀態。 原文地址:Functional-Light-JS 原文作者:Kyle Simpson-《You-Dont-Know-JS》作者 關于譯者:這是一個流淌著滬江血液的純粹工程:認真,是 HTML 最堅實的梁柱;...
閱讀 550·2021-11-25 09:44
閱讀 2636·2021-11-24 09:39
閱讀 2305·2021-11-22 15:29
閱讀 3520·2021-11-15 11:37
閱讀 3379·2021-09-24 10:36
閱讀 2507·2021-09-04 16:41
閱讀 992·2021-09-03 10:28
閱讀 1833·2019-08-30 15:55