關(guān)于正則

概念:

正則表達(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的作用妖啥; 
QQ截圖20161221221757.jpg
QQ截圖20161221224544.jpg

正則常用的兩種方法:

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)! 如下圖:

QQ截圖20161222001216.jpg

2 于是/!.+!/正則就會(huì)開(kāi)始匹配.苍柏,而 . 這個(gè)符號(hào)可以匹配除換行符外的全部字符,于是它就一直匹配到了最后姜贡,直到文本結(jié)束:

QQ截圖20161222001330.jpg

3 .號(hào)匹配完畢后试吁,開(kāi)始匹配后面的!,于是正則/!.+!/開(kāi)始往回匹配感嘆號(hào)!鲁豪,一直匹配到30后面的!潘悼,發(fā)現(xiàn)符合規(guī)則了,于是匹配出來(lái)的就是這一串字符串

QQ截圖20161222001722.jpg
所以會(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)! 如下圖:

QQ截圖20161222001216.jpg

2 然后進(jìn)行 . 的匹配宾添,但是與貪婪模式不同的是,它每匹配一次.
柜裸,就會(huì)往后匹配一次!缕陕,于是就出現(xiàn)了如下圖的結(jié)果:

QQ截圖20161222002227.jpg

3 因?yàn)間是全局匹配,所以該正則又會(huì)從頭開(kāi)始匹配第一個(gè)!疙挺,到了!30后扛邑,匹配成功第一個(gè)!和兩個(gè).,以及后面的!铐然,于是!30!也被匹配上了蔬崩,然后該正則又剩下的字符串開(kāi)始從新匹配恶座,而后面因?yàn)椴荒芷ヅ涑龅谝粋€(gè)!,于是就沒(méi)有匹配出來(lái):

QQ截圖20161222002554.jpg

下面做一些練習(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)明出處

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末东跪,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子鹰溜,更是在濱河造成了極大的恐慌虽填,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件曹动,死亡現(xiàn)場(chǎng)離奇詭異斋日,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)仁期,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門(mén)桑驱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人跛蛋,你說(shuō)我怎么就攤上這事熬的。” “怎么了赊级?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵押框,是天一觀的道長(zhǎng)弯屈。 經(jīng)常有香客問(wèn)我了讨,道長(zhǎng)泳猬,這世上最難降的妖魔是什么田藐? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮兑徘,結(jié)果婚禮上刚盈,老公的妹妹穿的比我還像新娘。我一直安慰自己挂脑,他們只是感情好藕漱,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著崭闲,像睡著了一般肋联。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上刁俭,一...
    開(kāi)封第一講書(shū)人閱讀 49,760評(píng)論 1 289
  • 那天橄仍,我揣著相機(jī)與錄音,去河邊找鬼牍戚。 笑死侮繁,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的翘魄。 我是一名探鬼主播鼎天,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼暑竟!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起育勺,我...
    開(kāi)封第一講書(shū)人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤但荤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后涧至,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體腹躁,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年南蓬,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了纺非。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡赘方,死狀恐怖烧颖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情窄陡,我是刑警寧澤炕淮,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站跳夭,受9級(jí)特大地震影響涂圆,放射性物質(zhì)發(fā)生泄漏们镜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一润歉、第九天 我趴在偏房一處隱蔽的房頂上張望模狭。 院中可真熱鬧,春花似錦踩衩、人聲如沸嚼鹉。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)反砌。三九已至,卻和暖如春萌朱,著一層夾襖步出監(jiān)牢的瞬間宴树,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工晶疼, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留酒贬,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓翠霍,卻偏偏與公主長(zhǎng)得像锭吨,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子寒匙,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • --------------------------正則的作用--------------------------...
    G_whk閱讀 613評(píng)論 1 5
  • 初衷:看了很多視頻零如、文章,最后卻通通忘記了锄弱,別人的知識(shí)依舊是別人的考蕾,自己卻什么都沒(méi)獲得。此系列文章旨在加深自己的印...
    DCbryant閱讀 3,993評(píng)論 0 20
  • 轉(zhuǎn)自: JS正則表達(dá)式一條龍講解会宪,從原理和語(yǔ)法到JS正則肖卧、ES6正則擴(kuò)展,最后再到正則實(shí)踐思路 溫馨提示:文章很長(zhǎng)...
    前端渣渣閱讀 1,802評(píng)論 1 32
  • 正則表達(dá)式指符合一定規(guī)則的表達(dá)式掸鹅,專(zhuān)門(mén)用于操作字符串塞帐。用一些特定的符號(hào)來(lái)表示一些代碼操作,以此來(lái)簡(jiǎn)化書(shū)寫(xiě)巍沙。只需要書(shū)...
    李斯維閱讀 749評(píng)論 1 11
  • 好尷尬
    昨天比較不愛(ài)你閱讀 237評(píng)論 0 0