摘要:正則表達(dá)式產(chǎn)生回溯的地方貪婪量詞前面的匹配的是,后面的匹配的是惰性量詞惰
查看原文站點(diǎn),更多擴(kuò)展內(nèi)容及更佳閱讀體驗(yàn)!正則表達(dá)式
查看原文:正則表達(dá)式
正則表達(dá)式是匹配模式,要么匹配字符,要么匹配位置。字符匹配 兩種模糊匹配
正則表達(dá)式能實(shí)現(xiàn)模糊匹配
模糊匹配,有兩個(gè)方向上的模糊:橫向和縱向
橫向模糊匹配橫向模糊指的是,一個(gè)正則可匹配的字符串的長(zhǎng)度不是固定的
實(shí)現(xiàn)方式是使用量詞。{m,n},表示連續(xù)出現(xiàn)最少m次,最多n次
/ab{2,5}c/匹配:第一個(gè)字符是a,接下來是2到5個(gè)字符b,最后是c。
var regex = /ab{2,5}c/g; var string = "abc abbc abbbc abbbbc abbbbbc abbbbbbc"; console.log(string.match(regex)); //[ "abbc", "abbbc", "abbbbc", "abbbbbc" ]縱向模糊匹配
縱向模糊,一個(gè)正則匹配的字符串,具體到某一位字符時(shí),它可以不是某個(gè)確定的字符,可以有多種可能
實(shí)現(xiàn)方式是使用字符組。[abc],表示該字符可以是a、b、c中的任何一個(gè)。
var regex = /a[123]b/g; var string = "a0b a1b a2b a3b a4b"; console.log(string.match(regex)); //[ "a1b", "a2b", "a3b" ]字符組
雖然叫字符組(字符類),但只是匹配其中一個(gè)字符。[abc]表示匹配一個(gè)字符,它可以是a、b、c。范圍表示法
字符組里的字符比較多,可以使用范圍表示法。
[123456abcdefGHIJKLM]可以寫成[1-6a-fG-M]。用連字符-來省略和簡(jiǎn)寫。
匹配a、-、z這三者中任意一個(gè)字符,可以寫成[-az]或[a-z]。要么放在開頭,要么放在結(jié)尾,要么轉(zhuǎn)義。
排除字符組縱向模糊匹配某位字符不能是a、b、c
[^abc]表示一個(gè)除a、b、c之外的任意一個(gè)字符。字符組的第一位放^(脫字符),表示求反的概念。
常見的簡(jiǎn)寫形式d就是[0-9]。表示一位數(shù)字。digit
D就是[^0-9]。表示除數(shù)字外的任意字符
w就是[0-9a-zA-Z]。表示數(shù)字、大小寫字母和下劃線。word
W就是[^0-9a-zA-Z]。非單詞字符
s就是[ v f]。表示空白符,包括空格、水平制表符、垂直制表符、換行符、回車符、換頁(yè)符。space
S就是[^ v f]。非空白符
.就是[^ u2028u2029]。通配符,表示所有任意字符。
匹配任意字符,可以使用[dD]、[wW]、[sS]、[^]中任意一個(gè)。量詞
量詞也稱重復(fù)。{m,n}簡(jiǎn)寫形式
{m,} 表示至少出現(xiàn)m次
{m} 等價(jià)于{m,m},表示出現(xiàn)m次
? 等價(jià)于{0,1},表示出現(xiàn)或不出現(xiàn)
+ 等價(jià)于{1,},表示出現(xiàn)至少一次。
* 等價(jià)于{0,},表示出現(xiàn)任意次,有可能不出現(xiàn)。
貪婪匹配和惰性匹配var regex = /d{2,5}/g; var string = "123 1234 12345 123456"; console.log(string.match(regex)); //[ "123", "1234", "12345", "12345" ]
貪婪匹配,就會(huì)盡可能多的匹配。
惰性匹配,就會(huì)盡可能少的匹配。
var regex = /d{2,5}?/g; var string = "123 1234 12345 123456"; console.log(string.match(regex)); //[ "12", "12", "34", "12", "34", "12", "34", "56" ]
/d{2,5}?/g 表示2到5次都行,當(dāng)2個(gè)就夠的時(shí)候,不再往下匹配。
通過在量詞后面加?就能實(shí)現(xiàn)惰性匹配,所有的惰性匹配情形
{m,n}?
{m,}?
??
+?
*?
.* 是貪婪模式
.*?是惰性模式
多選分支一個(gè)模式可以實(shí)現(xiàn)橫向和縱向模糊匹配。而多選分支可以支持多個(gè)子模式任選其一。
(p1|p2|p3)其中p1、p2和p3是子模式,用|(管道符)分隔,表示其中任何一個(gè)。
var regex = /good|nice/g; var string = "good idea, nice try."; console.log(string.match(regex)); //[ "good", "nice" ]
var regex = /good|goodbye/g; var string = "goodbye"; console.log( string.match(regex) ); // => ["good"]
var regex = /goodbye|good/g; var string = "goodbye"; console.log( string.match(regex) ); // => ["goodbye"]
以上得到的結(jié)果各不相同,分支結(jié)構(gòu)也是惰性的,即當(dāng)前面的匹配好了,后面的不再嘗試。
案例分析 匹配16進(jìn)制顏色值要求匹配
#ffbbad #Fc01DF #FFF #ffE
分析
表示一個(gè)16進(jìn)制字符,可以用字符組[0-9a-fA-F]
其中字符可以出現(xiàn)3或6次,需要是用量詞和分支結(jié)構(gòu)
使用分支結(jié)構(gòu)時(shí),需要注意順序
var regex = /#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})/g; var string = "#ffbbad #Fc01DF #FFF #ffE"; console.log(string.match(regex)); //[ "#ffbbad", "#Fc01DF", "#FFF", "#ffE" ]匹配時(shí)間
要求匹配
23:59 02:07
分析
共4位數(shù)字,第一位數(shù)字可以是[0-2]
當(dāng)?shù)?b>1位是2時(shí),第2位可以是[0-3],其他情況第2位是[0-9]
第3位數(shù)字是[0-5],第4位是[0-9]
var regex = /^([01][0-9]|[2][0-3]):[0-5][0-9]$/g;
要求匹配7:9,時(shí)分前面的0可以省略。
var regex = /^(0?[0-9]|1[0-9]|2[0-3]):(0?[0-9]|[1-5][0-9])$/g; var string = "7:9"; console.log(regex.test(string)); //true匹配日期
要求匹配 2017-06-10
分析
年,四位數(shù)字即可[0-9]{4}
月,共12個(gè)月,分兩種情況01、02、...和10、11、12,(0[1-9]|1[0-2])
年,最大31天,可用(0[1-9]|[12][0-9]|3[01])
var regex = /^[0-9]{4}-(0[0-9]|1[0-2])-(0[0-9]|[12][0-9]|3[01])$/g; console.log(regex.test("2017-10-20")); //truewindow操作系統(tǒng)文件路徑
F:studyjavascript egex egular expression.pdf F:studyjavascript egex F:studyjavascript F:
分析
整體模式是:盤符:文件夾文件夾文件夾
其中匹配F:,需要使用[a-zA-Z]:,其中盤符不區(qū)分大小寫,注意字符需要轉(zhuǎn)移
文件名或文件夾名,不能包含一些字符字符,此時(shí)需要排除字符組[^:*|"?
/]來表示合法字符。不能為空名,至少有一個(gè)字符,也就是要使用量詞+。
匹配文件夾,可用[^:*<>|"? /]+
另外文件夾,可以出現(xiàn)任意次。也就是([^:*<>|"? /]+)*。其中括號(hào)提供子表達(dá)式。
路徑的最后一部分可以是文件夾,沒有,因此需要添加([^:*<>|"? /]+)?
var regex = /^[a-zA-Z]:([^:*<>|"? /]+)*([^:*<>|"? /]+)?$/g;匹配id
要求從中提取出id="container"
var regex = /id=".*?"/; var string = ""; console.log(string.match(regex)[0]); //id="container"位置匹配
在ES5中共有6個(gè)錨字符
^$B(?=p)(?!p)$和^
^(脫字符)匹配開頭,在多行匹配中匹配行開頭
$(美元符號(hào))匹配結(jié)尾,在多行匹配中匹配結(jié)尾
把字符串的開頭和結(jié)尾用#替換
var result = "hello".replace(/^|$/g, "#"); console.log(result); //#hello#
多行匹配模式
var result = "I love javascript".replace(/^|$/gm, "#"); console.log(result); //#I# // #love# // #javascript#和B
是單詞邊界,具體就是w和W之間的位置,也包括w和W之間的位置,也包括w和$之間的位置
文件名是[JS] Lesson_01.mp4中的
var result = "[JS] Lesson_01.mp4".replace(//g, "#"); console.log(result); //[#JS#] #Lesson_01#.#mp4#(?=p)和(?!p)
(?=p),其中p是一個(gè)子模式,即p前面的位置
(?=l),表示l字符前面的位置
var result = "hello".replace(/(?=l)/g, "#"); console.log(result); //he#l#lo
(?!p)是(?=p)的反向操作
var result = "hello".replace(/(?!l)/g, "#"); console.log(result); //#h#ell#o#
分別是正向先行斷言和反向先行斷言,具體是(?<=p)和(?
(?=p)就是p前面的那個(gè)位置
位置的特性var result = /^^hello$$$/.test("hello"); console.log(result); // => true案例 不匹配任何東西的正則
/.^/數(shù)字的千位分隔符表示法
把12345678,變成12,345,678
使用(?=d{3}$)
var result = "12345678".replace(/(?=d{3}$)/g, ","); console.log(result); //12345,678
逗號(hào)出現(xiàn)的位置,要求后面3個(gè)數(shù)字一組,也就是d{3}至少出現(xiàn)一次
可以使用量詞+
var result = "12345678".replace(/(?=(d{3})+$)/g, ","); console.log(result); //12,345,678匹配其他案例
匹配位置不是開頭(?!^)
var string1 = "12345678"; var string2 = "123456789"; var reg = /(?!^)(?=(d{3})+$)/g; var result1 = string1.replace(reg, ","); console.log(result1); //12,345,678 var result2 = string2.replace(reg, ","); console.log(result2); //123,456,789驗(yàn)證密碼問題
密碼長(zhǎng)度6-12位,由數(shù)字、小寫字符和大寫字母組成,但必須至少包括2種字符。
簡(jiǎn)化
不考慮“但至少包括2種字符”這個(gè)條件
var reg = /^[0-9A-Za-z]{6,12}$/;
判斷是否含有某一種字符
如果要求必須包含數(shù)字,可以使用(?=.*[0-9])
var reg = /(?=.*[0-9])^[0-9A-Za-z]{6,12}$/;
同時(shí)包含具有兩種字符
同時(shí)包含數(shù)字和小寫字母,可以用(?=.*[0-9](?=.*[a-z]))
var reg = /(?=.*[0-9])(?=.*[a-z])^(0-9A-Za-z){6,12}$/;
同時(shí)包含數(shù)字和小寫字母
同時(shí)包含數(shù)字和大寫字母
同時(shí)包含小寫字母和大寫字母
同時(shí)包含數(shù)字、小寫字母和大寫字母
var reg = /((?=.*[0-9])(?=.*[a-z])|(?=.*[0-9])(?=.*[A-Z])|(?=.*[a-z])(?=.*[A-Z]))^[0-9A-Za-z]{6,12}$/;括號(hào)的作用
括號(hào)提供分組
引用某個(gè)分組,有兩種情形:在JS中引用,在正則表達(dá)式中應(yīng)用
分組和分支結(jié)構(gòu) 分組/a+/匹配連續(xù)出現(xiàn)的a,要匹配連續(xù)出現(xiàn)的ab時(shí),需要使用/(ab)+/
括號(hào)提供分組功能,使量詞+作用于ab這個(gè)整體
var regex = /(ab)+/g; var string = "ababa abbb ababab"; console.log(string.match(regex)); //[ "abab", "ab", "ababab" ]分支結(jié)構(gòu)
多選分支結(jié)構(gòu)(p1|p2)中括號(hào)的作用是提供了子表達(dá)式的所有可能
I love JavaScript I love Regular Expression
var regex = /^I love (JavaScript|Regular Expression)$/; console.log( regex.test("I love JavaScript") ); console.log( regex.test("I love Regular Expression") ); // => true // => true引用分組
括號(hào)的重要作用,可以進(jìn)行數(shù)據(jù)提取,以及更強(qiáng)大的替換操作
匹配日期yyyy-mm-dd
提取數(shù)據(jù)
提取出年、月、日
var regex = /(d{4})-(d{2})-(d{2})/; var string = "2018-06-18"; console.log(string.match(regex)); //[ "2018-06-18", "2018", "06", "18", index: 0, input: "2018-06-18" ]
match返回的一個(gè)數(shù)組,第一個(gè)元素是整體匹配結(jié)果,然后是各個(gè)分組(括號(hào))匹配的內(nèi)容,然后是匹配下標(biāo),最后是輸入的文本。(正則是否有修飾符g,match返回的數(shù)組格式是不一樣)
可以使用正則對(duì)象的exec方法
可以使用構(gòu)造函數(shù)的全局屬性$1至$9來獲取
var regex = /(d{4})-(d{2})-(d{2})/; var string = "2017-06-12"; regex.test(string); // 正則操作即可,例如 //regex.exec(string); //string.match(regex); console.log(RegExp.$1); // "2017" console.log(RegExp.$2); // "06" console.log(RegExp.$3); // "12"
替換
把yyyy-mm-dd格式,替換成mm/dd/yyyy
var regex = /(d{4})-(d{2})-(d{2})/; var string = "2017-06-12"; var result = string.replace(regex, "$2/$3/$1"); console.log(result); // => "06/12/2017"
其中replace中第二個(gè)參數(shù)用$1、$2、$3指代相應(yīng)的分組。等價(jià)于var regex=/(d{4})-(d{2})-(d{2})/反向引用
寫一個(gè)正則支持匹配以下三種格式:
2016-06-12 2016-06-12 2016.06.12
要求分割符前后一致,使用反向引用
var regex = /d{4}(-|/|.)d{2}1d{2}/; var string1 = "2017-06-12"; var string2 = "2017/06/12"; var string3 = "2017.06.12"; var string4 = "2016-06/12"; console.log( regex.test(string1) ); // true console.log( regex.test(string2) ); // true console.log( regex.test(string3) ); // true console.log( regex.test(string4) ); // false
1,表示的引用之前的分組(-|/|.)。不管它匹配到什么(比如-),1都匹配那個(gè)同樣的具體某個(gè)字符
2和3分別指代第二個(gè)和第三個(gè)分組
括號(hào)嵌套
以左括號(hào)(開括號(hào))為準(zhǔn)
var regex = /^((d)(d(d)))1234$/; var string = "1231231233"; console.log( regex.test(string) ); // true console.log( RegExp.$1 ); // 123 console.log( RegExp.$2 ); // 1 console.log( RegExp.$3 ); // 23 console.log( RegExp.$4 ); // 3
正則匹配模式
第一個(gè)字符是數(shù)字,比如說1,
第二個(gè)字符是數(shù)字,比如說2,
第三個(gè)字符是數(shù)字,比如說3,
接下來的是1,是第一個(gè)分組內(nèi)容,那么看第一個(gè)開括號(hào)對(duì)應(yīng)的分組是什么,是123,
接下來的是2,找到第2個(gè)開括號(hào),對(duì)應(yīng)的分組,匹配的內(nèi)容是1,
接下來的是3,找到第3個(gè)開括號(hào),對(duì)應(yīng)的分組,匹配的內(nèi)容是23,
最后的是4,找到第3個(gè)開括號(hào),對(duì)應(yīng)的分組,匹配的內(nèi)容是3。
引用不存在的分組
反向引用,引用前面的分組,在正則里引用了不存在的分組,正則不會(huì)報(bào)錯(cuò),只是匹配反向引用的字符本身非捕獲分組
前面出現(xiàn)的分組,都會(huì)捕獲它們匹配的數(shù)據(jù),以便后續(xù)引用,因此也稱它們是捕獲型分組
非捕獲分組?:p
var regex = /(?:ab)+/g; var string = "ababa abbb ababab"; console.log(string.match(regex)); //[ "abab", "ab", "ababab" ]案例 字符串trim方法模擬
trim方法是去掉字符串的開頭和結(jié)尾的空白符
第一種,匹配到開頭和結(jié)尾的空白符,然后替換成空白符
function trim(str) { return str.replace(/^s+|s+$/g, "") }
第二種,匹配整個(gè)字符串,然后用引用來提取出相應(yīng)的數(shù)據(jù)
function trim(str) { return str.replace(/^s*(.*?)s*$/g, "$1"); }
這里使用了惰性匹配*?,不然也會(huì)匹配最后一個(gè)空格之前的所有空格將每個(gè)單詞的首字母轉(zhuǎn)換成大寫
function titleize(str) { return str.toLowerCase().replace(/(?:^|s)w/g, function (c) { return c.toUpperCase(); }) } console.log(titleize("my name is epeli")); //My Name Is Epeli
思路是找到每個(gè)單詞的首字母,這里不適用非捕獲匹配也是可以的駝峰化
function camelize(str) { return str.replace(/[-_s]+(.)?/g, function (match, c) { return c ? c.toUpperCase() : ""; }) } console.log(camelize("-moz-transform")); //MozTransform
其中分組(.)表示首字母。單詞的界定是,前面的字符可以是多個(gè)連字符、下劃線以及空白符。中劃線化正則后面的?的目的,是為了應(yīng)對(duì)str尾部的字符可能不是單詞字符。
駝峰化的逆過程
function dasherize(str) { return str.replace(/([A-Z])/g,"-$1").replace(/[-_s]+/g,"-").toLowerCase(); } console.log(dasherize("MozTransform")); //-moz-transformhtml轉(zhuǎn)義和反轉(zhuǎn)義 匹配成對(duì)標(biāo)簽
要求匹配
regular expression laoyao bye bye
不匹配
wrong!
匹配一個(gè)開標(biāo)簽,使用正則<[^>]+>
匹配一個(gè)閉標(biāo)簽,使用[^>]+>
要求匹配成對(duì)標(biāo)簽,需要使用反向引用
var regex = /<([^>]+)>[dD]*1>/; var string1 = "regular expression "; var string2 = "laoyao bye bye
"; var string3 = "wrong!"; console.log(regex.test(string1)); // true console.log(regex.test(string2)); // true console.log(regex.test(string3)); // false
其中開標(biāo)簽<[^>]+>改成<([^>]+)>,使用括號(hào)的目的是為了后面使用反向引用,而提供分組
閉標(biāo)簽使用了反向引用1>
[dD]這個(gè)字符是數(shù)字或不是數(shù)字,也就是匹配任意字符
正則表達(dá)式回溯法 沒有回溯的匹配當(dāng)目標(biāo)字符串是abbbc時(shí),就沒有所謂的“回溯”。有回溯的匹配
如果目標(biāo)字符串是abbc,中間就有回溯常見的回溯形式
回溯法也稱試探法,基本思想:從問題的某一種狀態(tài)(初始狀態(tài))出發(fā),搜索從這種狀態(tài)出發(fā)所能達(dá)到的所有“狀態(tài)”,當(dāng)一條路走到“盡頭”的時(shí)候,再后退一步或若干步,從另一種可能狀態(tài)出發(fā),繼續(xù)搜索,直到所有的路徑(狀態(tài))都試探過。這種不斷前進(jìn)、不斷回溯尋找解的方法,稱作“回溯法”。
本質(zhì)上就是深度優(yōu)先搜索算法。其中退到之前的某一步這個(gè)過程,成為“回溯”。
正則表達(dá)式產(chǎn)生回溯的地方
貪婪量詞var string = "12345"; var regex = /(d{1,3})(d{1,3})/; console.log(string.match(regex)); //[ "12345", "123", "45", index: 0, input: "12345" ]
前面的d{1,3}匹配的是123,后面的d{1,3}匹配的是45惰性量詞
惰性量詞就是在貪婪量詞后面加個(gè)問好。表示盡可能少的匹配。
var string = "12345"; var regex = /(d{1,3}?)(d{1,3})/; console.log( string.match(regex) ); // => ["1234", "1", "234", index: 0, input: "12345"]
其中d{1,3}?只匹配到一個(gè)字符1,而后面的d{1,3}匹配了234
雖然惰性量詞不貪婪,但也會(huì)有回溯現(xiàn)象。
分支結(jié)構(gòu)分支也是惰性的,比如/can|candy/,去匹配字符串candy,得到的結(jié)果是can,因?yàn)榉种?huì)一個(gè)一個(gè)嘗試,如果前面的滿足,后面就不會(huì)再試驗(yàn)。正則表達(dá)式的拆分 結(jié)構(gòu)和操作符
分支結(jié)構(gòu),可能前面的子模式會(huì)形成了局部匹配,如果接下來表達(dá)式整體不匹配,仍會(huì)繼續(xù)嘗試剩下的分支。
在正則表達(dá)式中,操作符都體現(xiàn)在結(jié)構(gòu)中,即由特殊字符和匹配字符所代表的一個(gè)特殊整體。
JS正則表達(dá)式中,都有哪些結(jié)構(gòu)?
字符字面量、字符組、量詞、錨字符、分組、選擇分支、反向引用
具體含義
字面量,匹配一個(gè)具體字符,包括不用轉(zhuǎn)義的和需要轉(zhuǎn)義的。
比如a匹配字符a, 匹配換行符,.匹配小數(shù)點(diǎn)
字符組,匹配一個(gè)字符,可以是多種可能之一,
比如[0-9],表示匹配一個(gè)數(shù)字,d是簡(jiǎn)寫形式。
另外還有反義字符組,表示可以是除了特定字符之外任何一個(gè)字符,比如[^0-9]表示一個(gè)非數(shù)字字符,也有D的簡(jiǎn)寫形式
量詞,表示一個(gè)字符連續(xù)出現(xiàn),比如a{1,3}表示a字符連續(xù)出現(xiàn)3次。
常見簡(jiǎn)寫形式,a+表示a字符連續(xù)出現(xiàn)至少一次
錨點(diǎn),匹配一個(gè)位置,而不是字符。
比如^匹配字符串的開頭,
比如匹配單詞邊界
比如(?=d)表示數(shù)字前面的位置
分組,用括號(hào)表示一個(gè)整體,
比如(ab)+表示ab兩個(gè)字符連續(xù)出現(xiàn)多次,也可以使用非捕獲分組(?:ab)+
分支,多個(gè)子表達(dá)式多選一
比如abc|bcd表示式匹配abc或bcd字符子串
反向引用,比如2表示引用第2個(gè)分組
其中涉及到的操作符有
轉(zhuǎn)義符
括號(hào)和方括號(hào) (...)、(?:...)、(?=...)、(?!...)、[...]
量詞限定符 {m}、{m,n}、{m,}、?、*、+
位置和序列 ^、$、元字符、一般字符
管道符 |
操作符的優(yōu)先級(jí)從上至下,由高到低
/ab?(c|de*)+|fg/
由于括號(hào)的存在,(c|de*)是一個(gè)整體結(jié)構(gòu)
在(c|de*)中注意其中的量詞,因此e是一個(gè)整體結(jié)構(gòu)
因?yàn)榉种ЫY(jié)構(gòu)|優(yōu)先級(jí)最低,因此c是一個(gè)整體,而de*是另一個(gè)整體
同理,整個(gè)正則分成了a、b?、(...)+、f、g。而由于分支的原因,又可以分成ab?(c|de*)+和fg兩部分
注意要點(diǎn)匹配字符串整體問題
要匹配整個(gè)字符串,在正則前后中加上錨字符^和$
量詞連綴問題
每個(gè)字符為a、b、c任選其一 字符串的長(zhǎng)度是3的倍數(shù)
/([abc]{3})/
元字符轉(zhuǎn)義問題
元字符,就是正則中特殊含義的字符
所有結(jié)構(gòu)里,用到的元字符:
^、$、.、*、+、?、|、|、/、()、[]、{}、=、!、:、-、,
當(dāng)匹配上面的字符本身時(shí),可以一律轉(zhuǎn)義:
var string = "^$.*+?|/[]{}=!:-,"; var regex = /^$.*+?|/[]{}=!:-,/; console.log(regex.test(string)); // => true
其中string中的字符也要轉(zhuǎn)義
另外在string中也可以把每個(gè)字符轉(zhuǎn)義,轉(zhuǎn)義后的結(jié)果仍然是自身
字符組中的元字符
跟字符組相關(guān)的元字符有[]`、^、-,需要在會(huì)引起歧義的地方進(jìn)行轉(zhuǎn)義。例如開頭的^`必須轉(zhuǎn)義,不然會(huì)把整個(gè)字符組,看成反義字符組。
var string = "^$.*+?|/[]{}=!:-,"; var regex = /[^$.*+?|/[]{}=!:-,]/g; console.log( string.match(regex) );案例分析
身份證
/^(d{15}|d{17}[dxX])$/
因?yàn)?b>|的優(yōu)先級(jí)最低,所以正則分成了兩部分d{15}和d{17}[dxX]
d{15}表示15位連續(xù)數(shù)字
d{17}[dxX]表示17位連續(xù)數(shù)字,最后一位可以是數(shù)字或大小寫字母x
IPV4地址
(0{0,2}d|0?d{2}|1d{2}|2[0-4]d|25[0-5])(0{0,2}d|0?d{2}|1d{2}|2[0-4]d|25[0-5])
它是一個(gè)多選結(jié)構(gòu),分成5部分
0{0-2}d,匹配一位數(shù),包括0補(bǔ)齊。比如9、09、009
0?d{2},匹配兩位數(shù),包括0補(bǔ)齊,也包括一位數(shù)
1d{2},匹配100到199
2[0-4]d,匹配200-249
25[0-5],匹配250-255
正則表達(dá)式編程 四種操作 驗(yàn)證驗(yàn)證時(shí)正則表達(dá)式最直接的應(yīng)用,比如表單驗(yàn)證
判斷一個(gè)字符串中是否有數(shù)字
使用search
var regex = /d/; var string = "abc123"; console.log(!!~string.search(regex)); //true
使用test
var regex = /d/; var string = "abc123"; console.log( regex.test(string) ); // => true
使用match
var regex = /d/; var string = "abc123"; console.log( !!string.match(regex) ); // => true
使用exec
var regex = /d/; var string = "abc123"; console.log( !!regex.exec(string) ); // => true
其中,最常用的是test切分
切分,就是把目標(biāo)字符串切成段,例如JS中的split
比如目標(biāo)字符串html,css,javascript,按逗號(hào)來切分
var regex = /,/; var string = "html,css,javascript"; console.log(string.split(regex)); //[ "html", "css", "javascript" ]
日期格式
2018/06/20 2018.06.20 2018-06-20
可以使用split切出年月日
var regex = /D/; console.log("2018/06/20".split(regex)); console.log("2018.06.20".split(regex)); console.log("2018-06-20".split(regex)); // [ "2018", "06", "20" ] // [ "2018", "06", "20" ] // [ "2018", "06", "20" ]提取
此時(shí)正則通常要使用分組引用(分組捕獲)功能
match
var regex = /^(d{4})D(d{2})D(d{2})$/; var string = "2018-06-20"; console.log(string.match(regex)); //[ "2018-06-20", "2018", "06", "20", index: 0, input: "2018-06-20" ]
exec
var regex = /^(d{4})D(d{2})D(d{2})$/; var string = "2018-06-20"; console.log(regex.exec(string)); //[ "2018-06-20", "2018", "06", "20", index: 0, input: "2018-06-20" ]
test
var regex = /^(d{4})D(d{2})D(d{2})$/; var string = "2018-06-20"; regex.test(string); console.log(RegExp.$1, RegExp.$2, RegExp.$3); //2018 06 20
search
var regex = /^(d{4})D(d{2})D(d{2})$/; var string = "2018-06-20"; string.search(regex); console.log(RegExp.$1, RegExp.$2, RegExp.$3); //2018 06 20
replace
var regex = /^(d{4})D(d{2})D(d{2})$/; var string = "2018-06-20"; var date = []; string.replace(regex, function (match, year, month, day) { date.push(year, month, day); }); console.log(date); //[ "2018", "06", "20" ]
其中最常用的是match替換
把日期格式,從yyyy-mm-dd替換成yyyy/mm/dd:
var string = "2018-06-20"; var today = new Date(string.replace(/-/g, "/")); console.log(today); //2018-06-19T16:00:00.000Z
用于正則操作的方法,共有6個(gè),字符串實(shí)例4個(gè),正則實(shí)例2個(gè)
string#search
string#split
string#match
string#replace
RegExp#test
RegExp#exec
search和match的參數(shù)問題
字符串實(shí)例的4個(gè)方法參數(shù)都支持正則和字符串
但search和match把字符串轉(zhuǎn)換為正則
var string = "2018.06.20"; console.log(string.search("."));//0 //需要修改成下列形式之一 console.log(string.search("."));//4 console.log(string.search(/./));//4 console.log(string.match(".")); //[ "2", index: 0, input: "2018.06.20" ] //需要修改成下列形式之一 console.log(string.match(".")); //[ ".", index: 4, input: "2018.06.20" ] console.log(string.match(/./)); //[ ".", index: 4, input: "2018.06.20" ] console.log(string.split(".")); //[ "2018", "06", "20" ] console.log(string.replace(".", "/")); //2018/06.20
match返回結(jié)果的格式問題
match返回結(jié)果的格式,跟正則對(duì)象是否有修飾符g有關(guān)
var string = "2018.06.20"; var regex1=/(d+)/; var regex2=/(d+)/g; console.log(string.match(regex1)); //[ "2018", "2018", index: 0, input: "2018.06.20" ] console.log(string.match(regex2)); //[ "2018", "06", "20" ]
沒有g,返回的是標(biāo)準(zhǔn)匹配格式,數(shù)組的第一個(gè)元素時(shí)整體匹配的內(nèi)容,接下來是分組捕獲的內(nèi)容,然后是整體匹配的第一個(gè)下標(biāo),最后的輸入的目標(biāo)字符串
有g,返回的是所有匹配的內(nèi)容
當(dāng)沒有匹配時(shí),不管有沒有g都返回null
exec比match更強(qiáng)大
當(dāng)正則沒有g時(shí),使用match返回的信息比較多。但是有g后,就沒有關(guān)鍵信息index
而exec方法就能解決這個(gè)問題,它能接著上一次匹配后繼續(xù)匹配
var string = "2018.06.20"; var regex = /(d+)/g; console.log(regex.exec(string)); //[ "2018", "2018", index: 0, input: "2018.06.20" ] console.log(regex.lastIndex);//4 console.log(regex.exec(string)); // [ "06", "06", index: 5, input: "2018.06.20" ] console.log(regex.lastIndex);//7 console.log(regex.exec(string)); //[ "20", "20", index: 8, input: "2018.06.20" ] console.log(regex.lastIndex);//10 console.log(regex.exec(string));//null console.log(regex.lastIndex);//0
test整體匹配時(shí)需要使用^和$
test是看目標(biāo)字符串中是否有子串匹配正則,即有部分匹配即可。
要整體匹配,正則前后需要添加開頭和結(jié)尾
console.log( /123/.test("a123b") ); // => true console.log( /^123$/.test("a123b") ); // => false console.log( /^123$/.test("123") ); // => true
split相關(guān)注意事項(xiàng)
第一,它可以有第二個(gè)參數(shù),表示結(jié)果數(shù)組的最大長(zhǎng)度
var string = "html,css,javascript"; console.log( string.split(/,/, 2) ); // =>["html", "css"]
第二,正則使用分組時(shí),結(jié)果數(shù)組中是包含分隔符的
var string = "html,css,javascript"; console.log( string.split(/(,)/) ); // =>["html", ",", "css", ",", "javascript"]
replace是很強(qiáng)大的
replace有兩種使用形式,它的第二個(gè)參數(shù),可以是字符串,也可以是函數(shù)。
當(dāng)?shù)诙€(gè)參數(shù)是字符串時(shí),如下的字符有特殊的含義:
$1,$2,...,$99 匹配第1~99個(gè)分組里捕獲的文本
$& 匹配到的子串文本
$` 匹配到的子串的左邊文本
$" 匹配到的子串的右邊文本
$$ 美元符號(hào)
例如,把"2,3,5",變成"5=2+3":
var result = "2,3,5".replace(/(d+),(d+),(d+)/, "$3=$1+$2"); console.log(result); // => "5=2+3"
當(dāng)?shù)诙€(gè)參數(shù)是函數(shù)時(shí),該回調(diào)函數(shù)的參數(shù)具體:
"1234 2345 3456".replace(/(d)d{2}(d)/g, function(match, $1, $2, index, input) { console.log([match, $1, $2, index, input]); }); // => ["1234", "1", "4", 0, "1234 2345 3456"] // => ["2345", "2", "5", 5, "1234 2345 3456"] // => ["3456", "3", "6", 10, "1234 2345 3456"]
修飾符
g 全局匹配,即找到所有匹配的,單詞是global
i 忽略字母大小寫,單詞ingoreCase
m 多行匹配,只影響^和$,二者變成行的概念,即行開頭和行結(jié)尾。單詞是multiline
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/95564.html
摘要:本文內(nèi)容共正則表達(dá)式火拼系列正則表達(dá)式回溯法原理學(xué)習(xí)正則表達(dá)式,是需要懂點(diǎn)兒匹配原理的。正則表達(dá)式迷你書問世了讓幫你生成和解析參數(shù)字符串最全正則表達(dá)式總結(jié)驗(yàn)證號(hào)手機(jī)號(hào)中文郵編身份證地址等是正則表達(dá)式的縮寫,作用是對(duì)字符串執(zhí)行模式匹配。 JS 的正則表達(dá)式 正則表達(dá)式 一種幾乎可以在所有的程序設(shè)計(jì)語(yǔ)言里和所有的計(jì)算機(jī)平臺(tái)上使用的文字處理工具。它可以用來查找特定的信息(搜索),也可以用來查...
摘要:構(gòu)造函數(shù)可以有兩個(gè)字符串參數(shù),第一個(gè)參數(shù)包含正則表達(dá)式的主體部分。只讀的布爾值,說明這個(gè)正則表達(dá)式是否帶有修飾符。中正則的擴(kuò)展構(gòu)造函數(shù)在中,只能接受字符串作為參數(shù),允許其直接接受正則表達(dá)式作為參數(shù)。 上文傳送門:初探正則表達(dá)式 正則表達(dá)式是一個(gè)描述字符模式的對(duì)象,JavaScript 的 RegExp 類表示正則表達(dá)式,String 和 RegExp 都定義了方法,后者使用正則表達(dá)式進(jìn)...
摘要:正則表達(dá)式一直是里比較難以掌握的點(diǎn)。在中創(chuàng)建正則的兩種方式使用字面量這就是正則表達(dá)式的字面量語(yǔ)法,表示正則表達(dá)式的模式,為正則表達(dá)式的標(biāo)志。字面量形式的正則表達(dá)式一般使用較多,也推薦大家盡可能使用這種形式,簡(jiǎn)潔易讀,符合正常的使用習(xí)慣。 正則表達(dá)式一直是js里比較難以掌握的點(diǎn)。 看不懂,學(xué)不會(huì),記不住。 每次需要用到正則的時(shí)候,都需要再去查找資料。 今天花時(shí)間把正則的知識(shí)點(diǎn)總結(jié)下,希望...
摘要:注意本文將正則與中的正則分開討論。正則零寬斷言更多參考各種語(yǔ)言對(duì)于正則不同支持參考單行模式與多行模式通過設(shè)置正則表達(dá)式后的修飾符可開啟對(duì)應(yīng)的匹配模式單行模式和多行模式。 最近這段時(shí)間幫同學(xué)處理一些文檔, 涉及到一些結(jié)構(gòu)化文檔的工作大部分都得使用正則表達(dá)式, 之前對(duì)于正則的認(rèn)識(shí)大多來源于語(yǔ)言書上那幾頁(yè)的介紹, 自己也沒有用過幾次。這里將我之前感到模糊的概念作個(gè)整理。因?yàn)閷?duì)JS了解多點(diǎn),所...
摘要:選擇分組和引用正則表達(dá)式的語(yǔ)法還包括指定選擇項(xiàng)子表達(dá)式分組和引用前一子表達(dá)式的特殊字符。帶圓括號(hào)的表達(dá)式的另一個(gè)用途是允許在同一正則表達(dá)式的后部引用前面的子表達(dá)式。 正則表達(dá)式(regular expression)是一個(gè)描述字符模式的對(duì)象。JavaScript的 RegExp類 表示正則表達(dá)式,String和RegExp都定義了方法,后者使用正則表達(dá)式進(jìn) 行強(qiáng)大的模式匹配和文本檢索與...
摘要:最全正則表達(dá)式總結(jié)驗(yàn)證號(hào)手機(jī)號(hào)中文郵編身份證地址等是正則表達(dá)式的縮寫,作用是對(duì)字符串執(zhí)行模式匹配。學(xué)習(xí)目標(biāo)了解正則表達(dá)式語(yǔ)法在中使用正則表達(dá)式在中使 JS高級(jí)技巧 本篇是看的《JS高級(jí)程序設(shè)計(jì)》第23章《高級(jí)技巧》做的讀書分享。本篇按照書里的思路根據(jù)自己的理解和經(jīng)驗(yàn),進(jìn)行擴(kuò)展延伸,同時(shí)指出書里的一些問題。將會(huì)討論安全的類型檢測(cè)、惰性載入函數(shù)、凍結(jié)對(duì)象、定時(shí)器等話題。1. 安全的類型檢測(cè)...
閱讀 3544·2021-10-09 09:41
閱讀 2751·2021-10-08 10:18
閱讀 2187·2021-09-10 10:51
閱讀 2683·2021-09-10 10:50
閱讀 777·2021-09-09 09:33
閱讀 3386·2021-09-06 15:14
閱讀 3020·2019-08-30 11:06
閱讀 3250·2019-08-29 14:04