5、正則表達式

正則的解釋

正則表達式的創(chuàng)建

// 兩個正斜杠定義正則字面量的邊界
var reg = /test/;
// 構(gòu)造RegExp實例
var reg = new RegExp("test");

3個匹配標志的使用方法

// i 表示不區(qū)分大小寫
// g 表示全局匹配,而不是只匹配第一次出現(xiàn)的結(jié)果
// m 表示允許多行匹配
var reg = /test/igm;
var reg = new RegExp("test","igm");

正則的術語與操作符

匹配一個有限字符集中的某一個字符

// 表示匹配a,b,c中的任意一個字符
var reg = /[abc]/;

在中括號第一個括號后面加入^申鱼,表示匹配該組有限字符集以外的字符

// 表示匹配除了a,b,c以外的任意字符
var reg = /[^abc]/;

在字符集之間加入-愤诱,表示制定一個范圍

// 表示匹配a到m之間的任意字符,包括a和m
var reg = /[a-m]/;

轉(zhuǎn)義捐友,在正則表達式中淫半,字母和數(shù)字都能代表自己本身,但類似$-.[]等特殊字符都有其他含義楚殿,要匹配這些字符撮慨,需要用\對其進行轉(zhuǎn)義

// 表示匹配$字符
var reg = /\$/;

匹配的開始與結(jié)束

當^作為正則表達式的第一個字符時竿痰,表示必須從字符串的開頭進行匹配脆粥。

// 表示匹配以abc開頭的字符串
var reg = /^abc/;

當$作為正則表達式的最后一個字符時,表示該模式必須出現(xiàn)在字符串的結(jié)尾影涉。

// 表示匹配以abc結(jié)尾的字符串
var reg = /abc$/;

同時使用^和$時变隔,表示匹配模式必須包含整個字符串,即匹配模式就是字符串本身蟹倾,沒有任何其他字符匣缘。

// 表示匹配"abc"這個字符串,"abcabc"之類的不會匹配
var reg = /^abc$/;

重復出現(xiàn)

在一個字符后面加一個?鲜棠,表示該字符是可選的肌厨,也就是可以出現(xiàn)一次或不出現(xiàn)

// 表示匹配abc或者bc,
var reg = /a?bc/;

在一個字符后面加一個+豁陆,表示該字符可以出現(xiàn)一次或多次

// 表示匹配abc或者aaabc柑爸,
var reg = /a+bc/;

在一個字符后面加一個*,表示該字符可以出現(xiàn)零次或多次盒音,即任意次數(shù)

// 表示匹配abc或者aaabc或者bc表鳍,
var reg = /a*bc/;

在字符后跟花括號,在起重指定一個數(shù)字祥诽,表示該字符出現(xiàn)的次數(shù)

// 表示匹配aaaa譬圣,
var reg = /a{4}/;

在字符后跟花括號,在起重指定一個區(qū)間雄坪,表示該字符出現(xiàn)的次數(shù)區(qū)間

// 表示匹配a出現(xiàn)次數(shù)在4到10之間任意次數(shù)的字符串厘熟,包括4次和10次
var reg = /a{4,10}/;

次數(shù)區(qū)間第二個數(shù)值是可選的维哈,當沒有第二個數(shù)字是绳姨,表示匹配一個開區(qū)間

// 表示匹配a出現(xiàn)次數(shù)至少4次
var reg = /a{4,}/;

以上重復操作符可以是貪婪的或者非貪婪的笨农,默認情況下是貪婪的就缆,表示盡可能多的匹配,例如谒亦,匹配"aaa"字符串時竭宰,/a+/模式將匹配所有3個a空郊。在操作符后面加上?,表示非貪婪模式切揭,將進行最小限度的匹配狞甚,匹配"aaa"字符串時,/a+?/模式只會匹配一個a字符廓旬。因為一個a字符就滿足+表示的一次或多次的情況哼审。

預定義字符類

\t  水平制表符
\b  空格
\n  換行符
.   匹配除換行以外的任意字符
\d  匹配任意數(shù)字,等價于[0-9]
\D  匹配任意非數(shù)字孕豹,等價于[^0-9]
\w  匹配包括下劃線的任意單詞字符涩盾,等價于[A-Za-z0-9_]
\W  匹配任何非單詞字符,等價于[^A-Za-z0-9_]
\s  匹配任何空白符励背,包括空格春霍,制表符,換頁符等
\S  匹配任何非空白字符
\b  匹配單詞邊界
\B  匹配非單詞邊界

分組

在為匹配模式加上小括號叶眉,可以讓其成為一個分組址儒,后續(xù)添加的操作符可以影響整個分組。

// 表示匹配出現(xiàn)一次或連續(xù)多次的ab字符串衅疙,例如"xxxabxxx"莲趣,"xxxabababxxx"
var reg = /(ab)+/;

或操作符

豎線|表示或操作符

// 表示匹配a或b
var reg = /a|b/;
// 表示匹配出現(xiàn)一次或多次的"ab"或"ba"
var reg = /(ab)+|(ba)+/;

反向引用

反斜杠后面加一個數(shù)字表示要引用之前已經(jīng)匹配到的分組

// \1表示再匹配一次第一個分組([ab])匹配到的內(nèi)容,\2表示再匹配一次第二個分組(a)匹配到的內(nèi)容饱溢。
// 并且不是再次對分組中的模式進行匹配喧伞,而是對已經(jīng)匹配到的一模一樣的內(nèi)容進行精確匹配。
// 例如第一個分組([ab])匹配到了字符b理朋,\1匹配的就也必須是字符b
var reg = /([ab])(a)\1\2/;

反向引用常用來匹配元素的標簽

// \1表示對第一個分組(\w+)匹配到的內(nèi)容再次匹配絮识,內(nèi)容必須完全相同。因為標簽的開始和關閉是相同的嗽上。
var reg =/<(\w+)>.*<\/\1>/;
var a = "<strong>some thing</strong>";
console.log(reg.test(a)); // true

正則表達式的編譯

正則表達式的編譯發(fā)生在第一次被創(chuàng)建的時候次舌,而執(zhí)行則是發(fā)生在我們使用編譯過的正則表達式進行字符串匹配的時候。所以正則表達式只應該編譯一次兽愤,并將其保存在一個變量中以供后續(xù)使用彼念,這是一個重要的優(yōu)化過程。每次創(chuàng)建的正則表達式都是一個新的對象浅萧,其結(jié)果都是獨一無二的逐沙。
使用構(gòu)造器(new RegExp())可以通過動態(tài)的字符串創(chuàng)建正則表達式。

捕獲匹配的片段

匹配到的內(nèi)容中洼畅,每一個括號分組都是一個片段吩案,使用字符串的match()方法可以捕獲匹配的片段。
在非全局匹配時帝簇。其返回結(jié)果是一個數(shù)組徘郭,第一個索引的值是該匹配的完整結(jié)果靠益,之后的參數(shù)是每一個捕獲的片段。
在全局匹配時残揉。其返回結(jié)果也是一個數(shù)組胧后,但數(shù)組的值是所有的匹配結(jié)果,每一個匹配結(jié)果的捕獲片段是不會返回的抱环。

// 非全局匹配
var reg =/<(\w+)([^>]*)>/;
var a = '<div class="abc">hello</div>';
var b = a.match(reg);
console.log(b); // ["<div class="abc">", "div", " class="abc""]
// 全局匹配
var reg =/(\w+)([^>]*)>/g;
var a = '<div class="abc">hello</div>';
var b = a.match(reg);
console.log(b); // ["div class="abc">", "hello</div>"]

正則表達式的exec()方法壳快,可以對同一個字符串進行多次匹配,每一次匹配都會返回下一個匹配的結(jié)果

var reg =/<(\w+)([^>]*)>/g;
var a = '<div class="abc"><p>hello <span>world</span></p></div>';
var b = reg.exec(a);
var c = reg.exec(a);
var d = reg.exec(a);
console.log(b); // ["<div class="abc">"]
console.log(c); // ["<p>"]
console.log(d); // ["<span>"]

捕獲的引用

在replace()方法中镇草,可以使用$1眶痰,$2,$3這樣的語法來引用之前捕獲到的分組陶夜。

// 正則中的$1表示第一個捕獲到的分組中的內(nèi)容凛驮,即[A-Z]匹配到的內(nèi)容裆站。
var a = 'borderColor';
var b = a.replace(/([A-Z])/g,"-$1").toLowerCase();
console.log(b); // border-color

沒有捕獲的分組

在分組的左括號后加一個?:標記条辟,表示這個分組不需要被捕獲。

var reg = /(?:-[A-Z])/;
var a = 'border-Color';
var b = a.match(reg);
// 只返回了匹配的內(nèi)容宏胯,沒有返回分組中的內(nèi)容
console.log(b[1]);  // undefined

在不需要捕獲的時候羽嫡,盡量可能的使用非捕獲分組,減少引擎的工作量肩袍。

利用函數(shù)進行替換

replece()方法的第二個參數(shù)可以傳入一個函數(shù)杭棵,全局模式下每個匹配都會調(diào)用這個函數(shù),該函數(shù)有一個參數(shù)列表氛赐,分別為:

  1. 匹配的完整文本
  2. 匹配的捕獲魂爪,一個捕獲對應一個參數(shù)
  3. 匹配字符在元字符串中的索引
  4. 源字符串
function up(all,str) {
    return "-"+str.toLowerCase();
}
var a = 'borderBottomColor';
var b = a.replace(/([A-Z])/g,up);
console.log(b);  // border-bottom-color

利用這一特性可以修改一些數(shù)據(jù)的格式,例如將"a=1&a=2&a=3&b=4&b=5"修改為"a=1,2,3&b=4,5"艰管。

function up(str) {
    var keys = {}; // 保存數(shù)據(jù)

    str.replace(/([^=&]+)=([^&]+)/g,function (all, key, value) {
        keys[key]=keys[key]?keys[key]+","+value:value;
    });

    var result = [];
    for (var key in keys){
        result.push(key+"="+keys[key]);
    }
    return result.join("&");
}
var a = 'a=1&a=2&a=3&b=4&b=5';
console.log(up(a));  // a=1,2,3&b=4,5

常見問題

// 刪除前后空格滓侍,低端瀏覽器不支持trim()方法
var a = ' abc abc ';
console.log(a.replace(/^\s+|\s+$/g,""));  // abc abc
// 匹配換行符,/[\S\s]*/ 表示匹配所有字符
var a = 'abc\nabc';
console.log(/[\S\s]*/.exec(a)[0]); 
// 匹配Unicode
var a = '\u5FCD\u8005\u30D1\u30EF\u30FC';
console.log(a.match(/[\w\u0080-\uFFFF_-]+/)[0]);  // 忍者パワー
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末牲芋,一起剝皮案震驚了整個濱河市撩笆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌缸浦,老刑警劉巖夕冲,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異裂逐,居然都是意外死亡歹鱼,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進店門卜高,熙熙樓的掌柜王于貴愁眉苦臉地迎上來弥姻,“玉大人秩霍,你說我怎么就攤上這事∫涎簦” “怎么了铃绒?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長螺捐。 經(jīng)常有香客問我颠悬,道長,這世上最難降的妖魔是什么定血? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任赔癌,我火速辦了婚禮,結(jié)果婚禮上澜沟,老公的妹妹穿的比我還像新娘灾票。我一直安慰自己,他們只是感情好茫虽,可當我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布刊苍。 她就那樣靜靜地躺著,像睡著了一般濒析。 火紅的嫁衣襯著肌膚如雪正什。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天号杏,我揣著相機與錄音婴氮,去河邊找鬼。 笑死盾致,一個胖子當著我的面吹牛主经,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播庭惜,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼罩驻,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蜈块?” 一聲冷哼從身側(cè)響起鉴腻,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎百揭,沒想到半個月后爽哎,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡器一,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年课锌,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡渺贤,死狀恐怖雏胃,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情志鞍,我是刑警寧澤瞭亮,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站固棚,受9級特大地震影響统翩,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜此洲,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一厂汗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧呜师,春花似錦娶桦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至碰酝,卻和暖如春霎匈,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背送爸。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留暖释,地道東北人袭厂。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像球匕,于是被迫代替她去往敵國和親纹磺。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,614評論 2 353

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