概念:
正則表達(dá)式(Regular Expression)是計(jì)算機(jī)科學(xué)的一個(gè)概念峦树。正則表達(dá)式使用單個(gè)字符串來(lái)描述扰她、匹配一系列符合某個(gè)句法規(guī)則的字符串。在很多文本編輯器里犹赖,正則表達(dá)式通常被用來(lái)檢索、替換那些符合某個(gè)模式的文本卷仑。
通俗來(lái)講:正則表達(dá)式是用來(lái)處理字符串的峻村,可以用一些特定字符來(lái)描述字符串里字符出現(xiàn)的規(guī)則,從而匹配锡凝,提取或者替換符合某一個(gè)規(guī)則的字符串粘昨。比如(像文章關(guān)鍵字替換,密碼窜锯,手機(jī)等認(rèn)證张肾,郵箱等,都要用到正則)
創(chuàng)建:
- 第一種:構(gòu)造函數(shù)
var reg = new RegExp('hi','g')
锚扎; - 第二種:字面量
var reg = /hi/g
吞瞪;
修飾符:
1.g:global,全文搜索驾孔,不添加的話搜索到第一個(gè)結(jié)果停止搜索
2.i:ingore case芍秆,忽略大小寫(xiě),默認(rèn)大小寫(xiě)敏感
3.m:multiple lines翠勉,多行搜索
下面列子理解下g,i,m的作用妖啥;
正則常用的兩種方法:
test方法:test() 方法檢索字符串中的指定值。返回值是 true 或 false对碌。
var str = "my name is zyn"
var reg = /name/
console.log(reg.test(str)荆虱; //ture
exec方法:exec() 方法檢索字符串中的指定值。返回值是被找到的值朽们。如果沒(méi)有發(fā)現(xiàn)匹配怀读,則返回 null。
var str = "my name is zyn"
var reg = /name/
console.log(reg.exec(str)华坦; //name
字符類(lèi)
我們可以使用元字符[]來(lái)構(gòu)建一個(gè)簡(jiǎn)單的類(lèi)愿吹,所謂類(lèi)是指,符合某些特征的對(duì)象惜姐,是一個(gè)泛指犁跪,而不是特指某個(gè)字符了椿息,我們可以使用表達(dá)式 [abc]把字符a或b或c歸為一類(lèi),表達(dá)式可以匹配這類(lèi)的字符(如)
var str = "abcdefacbsq";
var reg =/[abc]/g;
console.log(str.match(reg));//["a", "b", "c", "a", "c", "b"]
var reg1 =/[a-e]/g;
console.log(str.match(reg1));//["a", "b", "c", "d", "e", "a", "c", "b"]
取反
元字符[]組合可以創(chuàng)建一個(gè)類(lèi)坷衍,我們還可以使用元字符^創(chuàng)建反向類(lèi)/負(fù)向類(lèi)寝优,反向類(lèi)的意思是不屬于XXX類(lèi)的內(nèi)容,表達(dá)式 [^abc] 表示不是字符a或b或c的內(nèi)容(如)
var str = "abcdefacbsq";
var reg =/[^abc]/g;
console.log(str.match(reg));//["d", "e", "f", "s", "q"]
var reg1 =/[^a-e]/g;
console.log(str.match(reg1));//["f", "s", "q"]
元字符
正則表達(dá)式中具有特殊意義的專(zhuān)用字符枫耳,可以用來(lái)規(guī)定其前導(dǎo)字符
如(( [ { \ ^ $ | ) ? * + .)后面會(huì)講到
并不是每個(gè)元字符都有特定的意義乏矾,在不同的組合中元字符有不同的意義,分類(lèi)看一下
字符 | 含義 |
---|---|
\t | 水平制表符 |
\r | 回車(chē)符 |
\n | 換行符 |
\f | 換頁(yè)符 |
\cX | 與X對(duì)應(yīng)的控制字符Ctrl+X |
\v | 垂直制表符 |
\0 | 空字符 |
預(yù)定義類(lèi)
字符 | 字符 | 含義 |
---|---|---|
. | [^\r\n] | 除了回車(chē)符和換行符之外的所有字符 |
\d | [0-9] | 數(shù)字字符 |
\D | [^0-9] | 非數(shù)字字符 |
\s | [\t\n\x0B\f\r] | 空白符 |
\S | [^\t\n\x0B\f\r] | 非空白符 |
\w | [a-zA-Z_0-9] | 單詞字符,字母,數(shù)字下劃線 |
\W | [^a-zA-Z_0-9] | 非單詞字符 |
邊界
字符 | 含義 |
---|---|
^ | 以xxx開(kāi)頭 |
$ | 以xxx結(jié)尾 |
\b | 單詞邊界 |
\B | 非單詞邊界 |
量詞
字符 | 含義 |
---|---|
迁杨? | 出現(xiàn)零次或一次(最多出現(xiàn)一次) |
+ | 出現(xiàn)一次或多次(至少出現(xiàn)一次) |
* | 出現(xiàn)零次或多次(任意次) |
{n} | 出現(xiàn)n次 |
{n,m} | 出現(xiàn)n到m次 |
{n,} | 至少出現(xiàn)n次 |
{,m} | 最多出現(xiàn)m次 |
貪婪模式與非貪婪模式
貪婪模式:量詞在默認(rèn)下是盡可能多的匹配的钻心;
非貪婪模式:讓正則表達(dá)式盡可能少的匹配,也就是說(shuō)一旦成功匹配不再繼續(xù)嘗試铅协,做法很簡(jiǎn)單捷沸,在量詞后加上?
簡(jiǎn)單來(lái)說(shuō)JS中的正則表達(dá)式的貪婪模式和非貪婪模式主要是匹配方式上有所不同(如)
var str = "how ! old are you! I am !30! year"
var reg =/!.+!/
console.log(str.match(reg) );//["! old are you! I am !30!"]
我們想要的是["! old are you!",!30!]可是為什么得到這個(gè)結(jié)果?
這是正則表達(dá)式的匹配方式導(dǎo)致的狐史。
正則表達(dá)式默認(rèn)的匹配的方式就是貪婪模式痒给。
- 貪婪模式:
1 首先在"how ! old are you! I am !30! year"
這個(gè)字符串中,使用/!.+!/進(jìn)行匹配骏全,那么這個(gè)正則式首先尋找的是一個(gè)感嘆號(hào)! 如下圖:
2 于是/!.+!/正則就會(huì)開(kāi)始匹配.苍柏,而 . 這個(gè)符號(hào)可以匹配除換行符外的全部字符,于是它就一直匹配到了最后姜贡,直到文本結(jié)束:
3 .號(hào)匹配完畢后试吁,開(kāi)始匹配后面的!,于是正則/!.+!/開(kāi)始往回匹配感嘆號(hào)!鲁豪,一直匹配到30后面的!潘悼,發(fā)現(xiàn)符合規(guī)則了,于是匹配出來(lái)的就是這一串字符串
所以會(huì)有以上的輸出爬橡,那怎么得到我們要的結(jié)果呢治唤?
改為費(fèi)貪婪模式:reg =/!.+?!/
var str = "how ! old are you! I am !30! year"
var reg =/!.+?!/g
console.log(str.match(reg) );//["! old are you!", "!30!"]
- 非貪婪模式:
1 首先在"how ! old are you! I am !30! year"
這個(gè)字符串中,使用/!.+!/進(jìn)行匹配糙申,那么這個(gè)正則式首先尋找的是一個(gè)感嘆號(hào)! 如下圖:
2 然后進(jìn)行 . 的匹配宾添,但是與貪婪模式不同的是,它每匹配一次.
柜裸,就會(huì)往后匹配一次!缕陕,于是就出現(xiàn)了如下圖的結(jié)果:
3 因?yàn)間是全局匹配,所以該正則又會(huì)從頭開(kāi)始匹配第一個(gè)!疙挺,到了!30后扛邑,匹配成功第一個(gè)!和兩個(gè).,以及后面的!铐然,于是!30!也被匹配上了蔬崩,然后該正則又剩下的字符串開(kāi)始從新匹配恶座,而后面因?yàn)椴荒芷ヅ涑龅谝粋€(gè)!,于是就沒(méi)有匹配出來(lái):
下面做一些練習(xí)題
1. \d沥阳,\w,\s,[a-zA-Z0-9],\b,.,*,+,?,x{3},^$分別是什么?
\d:數(shù)字字符跨琳;
\w:單詞字符,字母桐罕,數(shù)字下劃線脉让;
[a-zA-Z0-9]:取字母a到z任意字母的大小寫(xiě),和任意數(shù)字0到9功炮;
\b:單詞邊界溅潜;
.:除了回車(chē)符和換行符之外的所有字符;
+:出現(xiàn)一次或者多次;
?:出現(xiàn)0次或者一次死宣;
x{3}:x出現(xiàn)3次伟恶;
^$:^:表示匹配任何開(kāi)頭為輸出值的字符串,$:表示匹配任何結(jié)尾為輸出值的字符串毅该,兩者結(jié)合就是一個(gè)空字符;
2. 貪婪模式和非貪婪模式指什么?
貪婪模式和非貪婪模式潦牛,或者說(shuō)匹配優(yōu)先和忽略?xún)?yōu)先眶掌。標(biāo)準(zhǔn)量詞修飾的子表達(dá)式,在可匹配可不匹配的情況下巴碗,總會(huì)先嘗試進(jìn)行匹配朴爬,稱(chēng)貪婪模式,例如{n}橡淆、{m,n}召噩、*、+逸爵、. 具滴。
而非貪婪模式就是在可匹配可不匹配的情況下,總會(huì)優(yōu)先忽略匹配师倔,直到必須匹配才能使表達(dá)式匹配成功時(shí)构韵,才會(huì)進(jìn)行匹配。只要在標(biāo)準(zhǔn)量詞后加趋艘?即進(jìn)入非貪婪模式疲恢。例如{n}?、*?瓷胧、??显拳、+?。
3. 寫(xiě)一個(gè)函數(shù)trim(str)搓萧,去除字符串兩邊的空白字符
function trim(str){
return str.replace(/(^\s+)|(\s+$)/g,"");
}
console.log(trim('ab c'));//ab c
console.log(trim('ab c '));//ab c
console.log(trim(' ab c'));//ab c
console.log(trim(' abc '));//abc
console.log(trim(' abc '));//abc
console.log(trim(' a b c '));//a b c
4. 使用實(shí)現(xiàn) addClass(el, cls) hasClass(el, cls) removeClass(el,cls)使用正則
var test = document.getElementById('test')
function hasClass(el, cls) {
//左邊是開(kāi)頭或者空格,右邊是結(jié)尾或者空格
var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)', 'g');
// var reg = new RegExp('(\s|^)' + cls + '(\s|$)', 'g');
return reg.test(el.className);
}
function addClass(el, cls) {
var reg = new RegExp('(\\s|^)' + cls + '(\s|$)', 'g');
if (杂数!reg.test(el.className)) {
el.className = el.className + ' ' + cls;
}
}
function removeClass(el, cls) {
var reg = new RegExp('(\\s|^)' + cls + '(\s|$)', 'g');
//先替換成空格 再去掉多余的空格
if (reg.test(el.className)) {
el.className = el.className.replace(reg, ' ').replace(/\s{2,}/g, ' ');
}
}
5. 寫(xiě)一個(gè)函數(shù)isEmail(str)遇八,判斷用戶(hù)輸入的是不是郵箱
function isEmail(str){
var reg = /(\S)+[@]{1}(\S)+[.]{1}(\w)+/
return reg.test(str);
}
6. 寫(xiě)一個(gè)函數(shù)isPhoneNum(str),判斷用戶(hù)輸入的是不是手機(jī)號(hào)
function isPhone(str){
var reg = /^1[3-9]{10}$/;
return reg.test(str);
}
7 .寫(xiě)一個(gè)函數(shù)isValidUsername(str)耍休,判斷用戶(hù)輸入的是不是合法的用戶(hù)名(長(zhǎng)度6-20個(gè)字符刃永,只能包括字母、數(shù)字羊精、下劃線)
function isValidUsername(str){
var reg = /\w{6,20}$/
return reg.test(str)
}
8 .寫(xiě)一個(gè)函數(shù)isValidPassword(str),判斷用戶(hù)輸入的是不是合法密碼(長(zhǎng)度6-20個(gè)字符斯够,包括大寫(xiě)字母、小寫(xiě)字母喧锦、數(shù)字读规、下劃線至少包括兩種)
function isValidPassword(str){
if(str.length<6 || str.length>20){
return false;
}//長(zhǎng)度條件
if(/[^\w]/g.test(str))
{
return false;
}//其他字符;
if(/(^[a-z]+$)|(^[A-Z]+$)|(^\d+$)|(^_+$)/g.test(str)){
return fasle;
}//只有一種值得情況
return true;
}
9. 寫(xiě)一個(gè)正則表達(dá)式燃少,得到如下字符串里所有的顏色
var re = /*正則...*/
var subj = "color: #121212; background-color: #AA00ef; width: 12px; bad-colors: f#fddee #fd2 "
alert( subj.match(re) )
var reg = /#[A-Fa-f0-9]+/g;
var subj = "color: #121212; background-color: #AA00ef; width: 12px; bad-colors: f#fddee #fd2 ";
console.log(subj.match(reg));//["#121212", "#AA00ef", "#fddee", "#fd2"]
10.下面代碼輸出什么? 為什么? 改寫(xiě)代碼束亏,讓其輸出hunger, world.
var str = 'hello "hunger" , hello "world"';
var pat = /".*"/g;str.match(pat);
// 輸出結(jié)果是:"hunger" , hello "world",原因是因?yàn)?*使這個(gè)正則表達(dá)式處于貪婪模式阵具,所以在hunger前面有一個(gè)"碍遍,而world的后面也有一個(gè)",并且中間的所有字符都可以匹配.這個(gè)符號(hào)阳液,所以第一個(gè)雙引號(hào)和最后一個(gè)雙引號(hào)之間的字符全部都匹配上了怕敬;
var str = 'hello "hunger" , hello "world"';
var pat = /".*?"/g;
console.log(str.match(pat));//[""hunger"", ""world""]
//改寫(xiě)成了非貪婪模式;
11.補(bǔ)全如下正則表達(dá)式帘皿,輸出字符串中的注釋內(nèi)容. (可嘗試使用貪婪模式和非貪婪模式兩種方法)
str = '.. <!-- My -- comment \n test --> .. <!----> .. '
re = /.. your regexp ../str.match(re) // '<!-- My -- comment \n test -->', '<!---->'
非貪婪模式
str = '.. <!-- My -- comment \n test --> .. <!----> .. '
re = /<!--[\w\W]*?-->/g;
console.log(str.match(re)); // '<!-- My -- comment \n test -->', '<!---->'
str = '.. <!-- My -- comment \n test --> .. <!----> .. ';
re = /<[^\r]*?>/g;
console.log(str.match(re)); // '<!-- My -- comment \n test -->', '<!---->'
貪婪模式
str = '.. <!-- My -- comment \n test --> .. <!----> .. '
re = /<!--[^>]*-->/g;
console.log(str.match(re)); // '<!-- My -- comment \n test -->', '<!---->'
str = '.. <!-- My -- comment \n test --> .. <!----> .. ';
re = /[^.]*>/g;
console.log(str.match(re)); // '<!-- My -- comment \n test -->', '<!---->'
12. 補(bǔ)全如下正則表達(dá)式
var re = /* your regexp */
var str = '<> <a href="/"> <input type="radio" checked> <b>'
str.match(re) // '<a href="/">', '<input type="radio" checked>', '<b>'
var re = /<[a-z].*?>/g
var str = '<> <a href="/"> <input type="radio" checked> <b>'
console.log(str.match(re))
//["<a href="/">", "<input type="radio" checked>", "<b>"]
//非貪婪模式
var re = /<[^>]+>/g;
var str = '<> <a href="/"> <input type="radio" checked> <b>';
console.log(str.match(re));
// '<a href="/">', '<input type="radio" checked>', '<b>'
//貪婪模式
版權(quán)歸饑人谷--楠柒所有 如有轉(zhuǎn)載請(qǐng)標(biāo)明出處