正則大全

我們?cè)陂_(kāi)發(fā)中經(jīng)常會(huì)用到正則匹配,但是里面內(nèi)容龐大實(shí)在難以記清,今天我們就來(lái)梳理一下正則知識(shí),并在最后送上一些經(jīng)常用到的匹配方案,畢竟自己也是很害怕這一塊的。
1.replace
關(guān)于replace的用法,其實(shí)很多,我們會(huì)仔細(xì)講解。

var re = /apples/gi;
var str = "Apples are round, and apples are juicy.";
var newstr = str.replace(re, "oranges");

// oranges are round, and oranges are juicy.
console.log(newstr);

最基本的用法,g全局匹配,i忽略大小寫。

var re = /(\w+)\s(\w+)/;
var str = "John Smith";
var newstr = str.replace(re, "$2, $1");
// Smith, John
console.log(newstr);
交換了2個(gè)單詞的位置

var re = /(\w+)\s(\w+)/;
var str = "John Smith";
var newstr = str.replace(re, "$2, $1,$&");
// Smith, John,John Smith

\s是匹配空格,$&是匹配的子串,$1,$2分別字匹配項(xiàng)。
再來(lái)看一個(gè)

function replacer(match, p1, p2, p3, offset, string) {
  // p1 is nondigits, p2 digits, and p3 non-alphanumerics
  return [p1, p2, p3].join(' - ');
}
var newString = 'abc12345#$*%'.replace(/([^\d]*)(\d*)([^\w]*)/, replacer);

這里我們一目了然了把,看replcaer里面的參數(shù)就知道了。

我想問(wèn)一下大家知道$&和replacer函數(shù)里面最后一個(gè)參數(shù)string有啥區(qū)別
其實(shí)我剛剛做了個(gè)實(shí)驗(yàn),但是發(fā)現(xiàn)有問(wèn)題,就先不說(shuō)了,等下會(huì)有結(jié)論再講吧。

function f2c(x)
{
  function convert(str, p1, offset, s)
  {
    return ((p1-32) * 5/9) + "C";
  }
  var s = String(x);
  var test = /(\d+(\.\d*)?)F/g;
  return s.replace(test, convert);
}

函數(shù)傳入一個(gè)x,將其從華氏溫度轉(zhuǎn)成攝氏度。

2.exec
exec是正則里面會(huì)比較頻繁用到的,想想jquery的源碼,里面充斥的這樣的匹配。

var str = "javascript html css 555";
console.log(/(html) (css) (\d*)/.exec(str)); // ["html", index: 11, input: "javascript html css"]
output:
 ["html css 555", "html", "css", "555", index: 11, input: "javascript html css 555"]

可以看出來(lái)exec方法,會(huì)返回一個(gè)數(shù)組,第一個(gè)元素是符合匹配的字符串合集,第二個(gè)到第n個(gè)是表達(dá)式的子項(xiàng),index是符合首個(gè)匹配的索引,input是源字符串。

var x = " a.xxx.com b.xxx.com c.xxx.com";
var re = /\s?(.*?).xxx.com/g;
while( tempR = re.exec(x))
{
 console.log(tempR);
}
output:
[" a.xxx.com", "a", index: 0, input: " a.xxx.com b.xxx.com c.xxx.com"]
[" b.xxx.com", "b", index: 10, input: " a.xxx.com b.xxx.com c.xxx.com"]
[" c.xxx.com", "c", index: 20, input: " a.xxx.com b.xxx.com c.xxx.com"]
//一般用于循環(huán),將所有的匹配都輸出出來(lái),注意(.*?)匹配任何東西。

再來(lái)最后一個(gè)例子

var myRe = /ab*/g;
var str = 'abbcdefabh';
var myArray;
while ((myArray = myRe.exec(str)) !== null) {
  var msg = 'Found ' + myArray[0] + '. ';
  msg += 'Next match starts at ' + myRe.lastIndex;
  console.log(msg);
}
output:
Found abb. Next match starts at 3
Found ab. Next match starts at 9

注意lastIndex是指匹配的末項(xiàng)索引。

3.search
這個(gè)沒(méi)啥其他擴(kuò)展,咱們一筆帶過(guò)

var str = "hello world,hello world";
// 返回匹配到的第一個(gè)位置
console.log(str.search(/hello/)); // 0
// search方法不執(zhí)行全局匹配,它將忽略標(biāo)志g,同時(shí)它也沒(méi)有regexp對(duì)象的lastIndex的屬性,且總是從字符串開(kāi)始位置進(jìn)行查找,總是返回的是stringObject匹配的第一個(gè)位置。
console.log(str.search(/hello/g)); //0
console.log(str.search(/world/)); // 6

search方法都是從第一個(gè)位置開(kāi)始查找,并且沒(méi)有全局g的標(biāo)志。

4.match
初級(jí)用法和exec差不多,但是他全局匹配可以返回一個(gè)所有符合正則的數(shù)組。

var str = "hello world";
// 返回的數(shù)組內(nèi)有三個(gè)元素,第一個(gè)元素的存放的是匹配的文本,還有二個(gè)對(duì)象屬性;
index屬性表明的是匹配文本的起始字符在stringObject中的位置;input屬性聲明的是
對(duì)stringObject對(duì)象的引用;
console.log(str.match("hello")); // ["hello", index: 0, input: "hello world"]

var re = new RegExp('([0-9]+)-([0-9]+)-([0-9]+)');
var str = '2016-01-02';
var result = str.match(re); 
console.log(result.)); // [2016,01,02]

用了全局方法后會(huì)得到一個(gè)所有符合匹配的數(shù)組。

基本用法咱們講解完畢,我們來(lái)看一下高階用法。
1.貪婪模式和懶惰模式
相信大家對(duì)這個(gè)已經(jīng)有所耳聞了,那我們來(lái)看到底是啥。

var txt = '<a href=”http://google.com”>谷歌</a><a href=”http://baidu.com”>百度</a>'
var re1 = /\<a (.*?)\<\/a\>/g; //懶惰模式,盡可能少的匹配

console.log(re1.exec(txt)); 
//["<a href=”http://google.com”>谷歌</a>", "href=”http://google.com”>谷歌"]

console.log(re1.exec(txt));
//["<a href=”http://baidu.com”>百度</a>", "href=”http://baidu.com”>百度"]
這個(gè)是懶惰模式,跟我們之前講的exec并沒(méi)有啥區(qū)別,接著看下面這個(gè)。

var re2 = /\<a (.*)\<\/a\>/g; //貪婪模式,盡可能多的匹配, 區(qū)別在不加問(wèn)號(hào)
console.log(re2.exec(txt));
//["<a href=”http://google.com”>谷歌</a><a href=”http://baidu.com”>百度</a>", 
//"href=”http://google.com”>谷歌</a><a href=”http://baidu.com”>百度"]
console.log(re2.exec(txt));
//null
相信大家已經(jīng)看粗什么端倪來(lái)了,貪婪模式會(huì)把a(bǔ)標(biāo)簽中間所有的都檢索到,所以到值exec執(zhí)行一次
就沒(méi)有下文了。

2.捕獲分組和非捕獲分組
看起來(lái)卻是一臉蒙蔽,我們簡(jiǎn)短說(shuō)一下吧,畢竟這個(gè)屬于很少用的。

var str = "a1***ab1cd2***c2";  
var reg1 = /((ab)+\d+)((cd)+\d+)/i; 
var reg2 = /((?:ab)+\d+)((?:cd)+\d+)/i; 
console.log(str.match(reg1));
output:
["ab1cd2", "ab1", "ab", "cd2", "cd", index: 5, input: "a1***ab1cd2***c2"]
我們發(fā)現(xiàn)第二層括號(hào)里面的居然也北大引出來(lái)了,我們其實(shí)只想要外層的匹配
console.log(str.match(reg2));
output:
["ab1cd2", "ab1",  "cd2", index: 5, input: "a1***ab1cd2***c2"]

其實(shí)捕獲和不捕獲就是指的匹配想得子項(xiàng)是否被歸入到結(jié)果中,如果還不夠明白請(qǐng)看下面

var reg = /(?:\d{4})-(\d{2})-(\d{2})/
var reg1 = /(\d{4})-(\d{2})-(\d{2})/
var date = '2012-12-21'
reg.test(date)
RegExp.$1  
"12"
奇怪了第一個(gè)匹配的\d{4}明明是2012,為什么會(huì)輸出12呢
reg1.test(date)
RegExp.$1  
“2012”

反正我已經(jīng)是領(lǐng)略到了,如果還有疑問(wèn)可以看mdn開(kāi)發(fā)文檔

3.零寬斷言
零寬斷言就是下結(jié)論,例如ab,正則:a(?=b),匹配a并且向右看是b,得到的結(jié)果是a,斷言不會(huì)在匹配的內(nèi)容當(dāng)中,如果是a(?=c),則匹配不到任何內(nèi)容,因?yàn)槠ヅ鋋以后向右看并不是c。另外,零寬斷言分兩種:前瞻(Lookahead)和后顧(Lookbehind);但JavaScript只支持前瞻。

// 獲取字符串中以ing結(jié)尾的單詞的前半部分
var str = 'I love dancing but he likes playing';
var pattern = /\b\w+(?=ing\b)/g;
var ans = str.match(pattern);
console.log(ans);
output:
[danc,play]

// 獲取第五位不是i的單詞的前四位
var s = 'I love dancing but he likes singing';
var pattern = /\b\w{4}(?!i)/g;
var ans = s.match(pattern);
console.log(ans); // ["love", "like"]

下面以一個(gè)很經(jīng)典的例子結(jié)束本期

var str = '1234567890'
'12334565632'.replace(/(\d)(?=(\d{3})+$)/g, "$1,");
output:
"12,334,565,632"
記住要加上g,不然結(jié)果是12,334565632

又要結(jié)束了,下期會(huì)給大家?guī)?lái)前端工具gulp的文章。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,732評(píng)論 6 539
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,214評(píng)論 3 426
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 177,781評(píng)論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,588評(píng)論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,315評(píng)論 6 410
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,699評(píng)論 1 327
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,698評(píng)論 3 446
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,882評(píng)論 0 289
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,441評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,189評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,388評(píng)論 1 372
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,933評(píng)論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,613評(píng)論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 35,023評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 36,310評(píng)論 1 293
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,112評(píng)論 3 398
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,334評(píng)論 2 377

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