摘要:用匹配的模式切割,第二個參數是限制返回結果的最大數量匹配規則字面量字符和元字符大部分字符在正則表達式中,就是字面的含義,比如匹配,匹配。它們叫做元字符,主要有以下幾個。相比之下,點號作為元字符是不包括換行符的。
1.概述
正則表達式(regular expression)是一種表達文本模式(即字符串結構)的方法。
創建方式有兩種方式:
一種是使用字面量,以斜杠表示開始和結束。
var regex = /xyz/
另一種是使用RegExp構造函數。
var regex = new RegExp("xyz");
它們的主要區別是,第一種方法在引擎編譯代碼時,就會新建正則表達式,第二種方法在運行時新建正則表達式,所以前者的效率較高。而且,前者比較便利和直觀,所以實際應用中,基本上都采用字面量定義正則表達式。
2.實例屬性i:忽略大小寫
m:多行模式
g:全局搜索
3.實例方法 3.1 RegExp.prototype.test()正則實例對象的test方法返回一個布爾值,表示當前模式是否能匹配參數字符串。
/小智/.test("小智 終身學習執行者") // true
reg.exec(str) 返回匹配結果數組,不匹配則返回null,每執行一次exec就向后匹配一次
3.2 RegExp.prototype.exec()3.2.1 reg.exec(str) 返回匹配結果數組,不匹配則返回null,每執行一次exec就向后匹配一次
var s = "_x_x"; var r1 = /x/; var r2 = /y/; r1.exec(s) // ["x"] r2.exec(s) // null
3.2.1.2如果表達式里有括號(),稱為組匹配,返回結果中,第一個是整體匹配結果,后面依次是每個括號匹配的結果
var s = "_x_x"; var r = /_(x)/; r.exec(s) // ["_x", "x"]
exec方法的返回數組還包含以下兩個屬性:
input:整個原字符串。
index:整個模式匹配成功的開始位置(從0開始計數)。
var r = /a(b+)a/; var arr = r.exec("_abbba_aba_"); arr // ["abbba", "bbb"] arr.index // 1 arr.input // "_abbba_aba_"
3.2.3 如果表達式中有g選項進行全局搜索,則可以多次使用 exec,下次的匹配從上次的結果后開始
var reg = /a/g; var str = "abc_abc_abc" var r1 = reg.exec(str); r1 // ["a"] r1.index // 0 reg.lastIndex // 1 var r2 = reg.exec(str); r2 // ["a"] r2.index // 4 reg.lastIndex // 5 var r3 = reg.exec(str); r3 // ["a"] r3.index // 8 reg.lastIndex // 9 var r4 = reg.exec(str); r4 // null reg.lastIndex // 04.字符串的實例方法 4.1 str.match(reg),與 reg.exec相似,但是,如果使用g選項,則str.match一次性返回所有結果。
var s = "abba"; var r = /a/g; s.match(r) // ["a", "a"] r.exec(s) // ["a"]4.2 str.search(reg) ,返回匹配成功的第一個位置,如果沒有任何匹配,則返回-1。
"_x_x".search(/x/) // 14.3 str.replace(reg,newstr) ;
用第一個參數reg去匹配,用第二個參數newstr 去替換,正則表達式如果不加g修飾符,就替換第一個匹配成功的值,否則替換所有匹配成功的值。
"aaa".replace("a", "b") // "baa" "aaa".replace(/a/, "b") // "baa" "aaa".replace(/a/g, "b") // "bbb"4.4 str.split(reg[,maxLength]) 用匹配的模式切割,第二個參數是限制返回結果的最大數量 5. 匹配規則 5.1 字面量字符和元字符
大部分字符在正則表達式中,就是字面的含義,比如/a/匹配a,/b/匹配b。如果在正則表達式之中,某個字符只表示它字面的含義(就像前面的a和b),那么它們就叫做“字面量字符”(literal characters)。
除了字面量字符以外,還有一部分字符有特殊含義,不代表字面的意思。它們叫做“元字符”(metacharacters),主要有以下幾個。
(1) 點字符(.)
點字符(.)匹配除回車(r)、換行(n) 、行分隔符(u2028)和段分隔符(u2029)以外的所有字符。
/c.t/
上面代碼中,c.t匹配c和t之間包含任意一個字符的情況,只要這三個字符在同一行,比如cat、c2t、c-t等等,但是不匹配coot。
(2)位置字符
^ 表示字符串的開始位置
$ 表示字符串的結束位置
// test必須出現在開始位置 /^test/.test("test123") // true // test必須出現在結束位置 /test$/.test("new test") // true // 從開始位置到結束位置只有test /^test$/.test("test") // true /^test$/.test("test test") // false
(3)選擇符(|)
豎線符號(|)在正則表達式中表示“或關系”(OR),即cat|dog表示匹配cat或dog。
/11|22/.test("911") // true
上面代碼中,正則表達式指定必須匹配11或22。
5.2 轉義符正則表達式中那些有特殊含義的元字符,如果要匹配它們本身,就需要在它們前面要加上反斜杠。比如要匹配+,就要寫成+。
/1+1/.test("1+1") // false /1+1/.test("1+1") // true
正則表達式中,需要反斜杠轉義的,一共有12個字符:^、.、[、$、(、)、|、*、+、?、{和。需要特別注意的是,如果使用RegExp方法生成正則對象,轉義需要使用兩個斜杠,因為字符串內部會先轉義一次。
(new RegExp("1+1")).test("1+1") // false (new RegExp("1+1")).test("1+1") // true5.3 字符類
字符類(class)表示有一系列字符可供選擇,只要匹配其中一個就可以了。所有可供選擇的字符都放在方括號內,比如[xyz] 表示x、y、z之中任選一個匹配。
/[abc]/.test("hello world") // false /[abc]/.test("apple") // true
有兩個字符在字符類中有特殊含義。
(1)脫字符(^)
如果方括號內的第一個字符是[^xyz]表示除了x、y、z之外都可以匹配:
/[^abc]/.test("hello world") // true /[^abc]/.test("bbc") // false
如果方括號內沒有其他字符,即只有[^],就表示匹配一切字符,其中包括換行符。相比之下,點號作為元字符(.)是不包括換行符的。
var s = "Please yes make my day!"; s.match(/yes.*day/) // null s.match(/yes[^]*day/) // [ "yes make my day"]
上面代碼中,字符串s含有一個換行符,點號不包括換行符,所以第一個正則表達式匹配失敗;第二個正則表達式[^]包含一切字符,所以匹配成功。
(2)連字符(-)
某些情況下,對于連續序列的字符,連字符(-)用來提供簡寫形式,表示字符的連續范圍。比如,[abc]可以寫成[a-c],[0123456789]可以寫成[0-9],同理[A-Z]表示26個大寫字母。
/a-z/.test("b") // false /[a-z]/.test("b") // true
以下都是合法的字符類簡寫形式。
[0-9.,] [0-9a-fA-F] [a-zA-Z0-9-] [1-31]
上面代碼中最后一個字符類[1-31],不代表1到31,只代表1到3。
另外,不要過分使用連字符,設定一個很大的范圍,否則很可能選中意料之外的字符。最典型的例子就是[A-z],表面上它是選中從大寫的A到小寫的z之間52個字母,但是由于在 ASCII 編碼之中,大寫字母與小寫字母之間還有其他字符,結果就會出現意料之外的結果。
/[A-z]/.test("") // true
上面代碼中,由于反斜杠("")的ASCII碼在大寫字母與小寫字母之間,結果會被選中。
5.4 預定義模式預定義模式指的是某些常見模式的簡寫方式。
d 匹配0-9之間的任一數字,相當于[0-9]。
D 匹配所有0-9以外的字符,相當于[^0-9]。
w 匹配任意的字母、數字和下劃線,相當于[A-Za-z0-9_]。
W 除所有字母、數字和下劃線以外的字符,相當于[^A-Za-z0-9_]。
s 匹配空格(包括換行符、制表符、空格符等),相等于[ vf]。
S 匹配非空格的字符,相當于[^ vf]。
b 匹配詞的邊界。
B 匹配非詞邊界,即在詞的內部。
// s 的例子 /sw*/.exec("hello world") // [" world"] // 的例子 /world/.test("hello world") // true /world/.test("hello-world") // true /world/.test("helloworld") // false // B 的例子 /Bworld/.test("hello-world") // false /Bworld/.test("helloworld") // true
通常,正則表達式遇到換行符(n)就會停止匹配。
var html = "Hello world!"; /.*/.exec(html)[0] // "Hello"
上面代碼中,字符串html包含一個換行符,結果點字符(.)不匹配換行符,導致匹配結果可能不符合原意。這時使用s字符類,就能包括換行符。
var html = "Hello world!"; /[Ss]*/.exec(html)[0] // "Hello world!"
上面代碼中,[Ss]指代一切字符。
5.5 重復類模式的精確匹配次數,使用大括號({})表示。{n}表示恰好重復n次,{n,}表示至少重復n次,{n,m}表示重復不少于n次,不多于m次。
/lo{2}k/.test("look") // true /lo{2,5}k/.test("looook") // true
上面代碼中,第一個模式指定o連續出現2次,第二個模式指定o連續出現2次到5次之間。
5.6 量詞符*. ? 問號表示某個模式出現0次或1次,等同于{0, 1}。
*. * 星號表示某個模式出現0次或多次,等同于{0,}。
*. + 加號表示某個模式出現1次或多次,等同于{1,}。
上一小節的三個量詞符,默認情況下都是最大可能匹配,即匹配直到下一個字符不滿足匹配規則為止。這被稱為貪婪模式。
var s = "aaa"; s.match(/a+/) // ["aaa"]
上面代碼中,模式是/a+/,表示匹配1個a或多個a,那么到底會匹配幾個a呢?因為默認是貪婪模式,會一直匹配到字符a不出現為止,所以匹配結果是3個a。
如果想將貪婪模式改為非貪婪模式,可以在量詞符后面加一個問號。
var s = "aaa"; s.match(/a+?/) // ["a"]
除了非貪婪模式的加號,還有非貪婪模式的星號(*)和非貪婪模式的問號(?)
+?:表示某個模式出現1次或多次,匹配時采用非貪婪模式。
*?:表示某個模式出現0次或多次,匹配時采用非貪婪模式。
??:表格某個模式出現0次或1次,匹配時采用非貪婪模式。
5.8 組匹配(1)概述
正則表達式的括號表示分組匹配,括號中的模式可以用來匹配分組的內容。
/fred+/.test("fredd") // true /(fred)+/.test("fredfred") // true
上面代碼中,第一個模式沒有括號,結果+只表示重復字母d,第二個模式有括號,結果+就表示匹配fred這個詞。
下面是另外一個分組捕獲的例子。
var m = "abcabc".match(/(.)b(.)/); m // ["abc", "a", "c"]
上面代碼中,正則表達式/(.)b(.)/一共使用兩個括號,第一個括號捕獲a,第二個括號捕獲c。
注意,使用組匹配時,不宜同時使用g修飾符,否則match方法不會捕獲分組的內容。
var m = "abcabc".match(/(.)b(.)/g); m // ["abc", "abc"]
正則表達式內部,還可以用n引用括號匹配的內容,n是從1開始的自然數,表示對應順序的括號。
/(.)b(.)1b2/.test("abcabc") // true
上面的代碼中,1表示第一個括號匹配的內容(即a),2表示第二個括號匹配的內容(即c)。
(2)非捕獲組
(?:x)稱為非捕獲組(Non-capturing group),表示不返回該組匹配的內容,即匹配的結果中不計入這個括號。
非捕獲組的作用請考慮這樣一個場景,假定需要匹配foo或者foofoo,正則表達式就應該寫成/(foo){1, 2}/,但是這樣會占用一個組匹配。這時,就可以使用非捕獲組,將正則表達式改為/(?:foo){1, 2}/,它的作用與前一個正則是一樣的,但是不會多帶帶輸出括號內部的內容。
var m = "abc".match(/(?:.)b(.)/); m // ["abc", "c"]
上面代碼中的模式,一共使用了兩個括號。其中第一個括號是非捕獲組,所以最后返回的結果中沒有第一個括號,只有第二個括號匹配的內容。
(3)先行斷言
x(?=y)稱為先行斷言(Positive look-ahead),x只有在y前面才匹配,y不會被計入返回結果。比如,要匹配后面跟著百分號的數字,可以寫成/d+(?=%)/。
“先行斷言”中,括號里的部分是不會返回的。
var m = "abc".match(/b(?=c)/); m // ["b"]
上面的代碼使用了先行斷言,b在c前面所以被匹配,但是括號對應的c不會被返回。
(4)先行否定斷言
x(?!y)稱為先行否定斷言(Negative look-ahead),x只有不在y前面才匹配,y不會被計入返回結果。比如,要匹配后面跟的不是百分號的數字,就要寫成/d+(?!%)/。
/d+(?!.)/.exec("3.14") // ["14"]
上面代碼中,正則表達式指定,只有不在小數點前面的數字才會被匹配,因此返回的結果就是14。
6. 實戰 6.1 消除字符串首尾兩端的空格var str = " #id div.class "; str.replace(/^s+|s+$/g, "") // "#id div.class"6.2 驗證手機號碼
var reg = /1[24578]d{9}/; reg.test("154554568997"); //true reg.test("234554568997"); //false6.3 把手機號碼替換成 *
var reg = /1[24578]d{9}/; var str = "姓名:張三 手機:18210999999 性別:男"; str.replace(reg, "***") //"姓名:張三 手機:*** 性別:男"6.4 匹配網頁標簽
var strHtlm = "小智小智6.5 替換敏感字222222@.qq.com小智小智"; var reg = /<(.+)>.+1>/; strHtlm.match(reg); // ["222222@.qq.com"]
let str = "中國共產黨中國人民解放軍中華人民共和國"; let r = str.replace(/中國|軍/g, input => { let t = ""; for (let i = 0; i6.6 千位分隔符 let str = "100002003232322"; let r = str.replace(/(d)(?=(?:d{3})+$)/g, "$1,"); console.log(r); //100,002,003,232,322參考鏈接https://developer.mozilla.org...
https://wangdoc.com/javascrip...
你的點贊是我持續分享好東西的動力,歡迎點贊!
一個笨笨的碼農,我的世界只能終身學習!
更多內容請關注公眾號《大遷世界》!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/98153.html
摘要:對前端來說,使用的場景不多,但是像微信端的對話系統的表情包,就使用到了一個特定的規則。我是一個前端,工作年了,現在失業,想進入騰訊工作,這是我的聯系方式這個正則雖 我發現有個別字符被這個編輯器給刷掉了,但是灰色區域顯示正常,以灰色區域代碼為準 什么玩意? 在我剛開始學習編程的時候,就聽過正則了,也聽說正則很牛逼,懂正則的更牛逼。但是苦于沒有人指點,也沒有使用正則的場景,自己看教程又懵逼...
摘要:本文接上篇,基礎部分相對薄弱的同學請移步正則表達式學習筆記一理論基礎。正則表達式標志符全局匹配,即找到所有匹配的。方法返回結果的格式不一致問題這個問題上文正則表達式學習筆記一理論基礎也有體現,這里再單獨拿來說一說,以加深記憶。 showImg(https://segmentfault.com/img/remote/1460000014261596?w=600&h=338); 本文接上篇...
摘要:正則表達式使用單個字符串來描述匹配一系列匹配某個句法規則的字符串。接下來,是在手機正則里面已經出現了。序列匹配而則匹配。分組與反向引用分組,又稱為子表達式。把正則表達式拆分成小表達式。 本文轉載自網絡。轉載編輯過程中,可能有遺漏或錯誤,請以原文為準。原文作者:水墨寒湘原文鏈接:https://juejin.im/post/582dfc... 正則表達式對于我來說一直像黑暗魔法一樣的存...
閱讀 2657·2019-08-30 15:53
閱讀 2879·2019-08-29 16:20
閱讀 1086·2019-08-29 15:10
閱讀 1026·2019-08-26 10:58
閱讀 2198·2019-08-26 10:49
閱讀 637·2019-08-26 10:21
閱讀 707·2019-08-23 18:30
閱讀 1640·2019-08-23 15:58