JS正則表達(dá)式從入門到夠用

如果覺得還有點用糟需,請您給我一個贊暂论!您的贊是我堅持下去的動力

設(shè)想我們是否遇到這些問題?

  • 一個url的參數(shù)列表
    var str= "?am_id=2&approach=test&type=2&phone=137000";

    • 取出type的值往果?
    • 替換type的值筑公?
    • 直接刪除type這個參數(shù)
    • 取出所有符合規(guī)則 參數(shù)=值 的內(nèi)容
  • 一個替換字符串的案例
    var str = "{param1} name is {param2}";

    • 將{param1}替換為my,將{param2}替換為changxu 孽水,結(jié)果變?yōu)榱?my name is changxu
    • 將符合規(guī)則“{參數(shù)名}”格式的字符串票腰,整個替換掉,替換的目標(biāo)字符串根據(jù)"參數(shù)名"女气。
js中正則的使用
  • /正則表達(dá)式/.test("字符串");
  • var patt = new RegExp("正則表達(dá)式","擴(kuò)展參數(shù)");
    patt.test("字符串")

Step1:常用符號

  • 用于代表位置的
字符 含義
^ 字符串開始位置,也就是第一個字符位置
$ 字符串結(jié)尾位置,也就是最后一個字符位置
  • 用于檢測匹配的表達(dá)式次數(shù)杏慰,可以稱為量詞
字符 含義
* 匹配這個符號之前的表達(dá)式,任意次數(shù)
+ 匹配這個符號之前的表達(dá)式炼鞠,至少1次
? 匹配這個符號之前的表達(dá)式缘滥,至少0次或者1次,如果?之前的是一個量詞描述則代表非貪婪模式盡可能匹配少 '123456'.replace(/\d{2,4}/g,'*')結(jié)果為**,而'123456'.replace(/\d{2,4}?/g,'*')結(jié)果為***
{n} 匹配這個符號之前的表達(dá)式谒主,n次
{n,} 匹配這個符號之前的表達(dá)式朝扼,至少n次
{n,m} 匹配這個符號之前的表達(dá)式,>=n && <=m 次之間
  • 組成表達(dá)式需要的參數(shù)
字符 含義
. 匹配 \r\n 外的任意字符
x|y 匹配x或者y任意一個霎肯,x和y可以是字符也可以是表達(dá)式
[xyz] 匹配括號內(nèi)的任意一個字符
[^xyz] 匹配除了括號內(nèi)的字符外的字符
[a-z] 匹配a-z之間的任意一個字符
[a-zA-Z] 匹配a-z或A-Z之間的任意一個字符
[0-9] 匹配0-9之間任意一個字符,等價于\d
  • 特殊作用
字符 含義
( ) 將()范圍內(nèi)符合表達(dá)式的結(jié)果輸出到數(shù)組內(nèi)擎颖,最多可以存放9組[0]-[9]
(?:表達(dá)式)) 不會緩存括號內(nèi)的數(shù)據(jù)
(?=表達(dá)式)) 符合匹配的字符串位置之前(并且不會緩存括號內(nèi)的數(shù)據(jù))
(?!表達(dá)式)) 不匹配表達(dá)式的內(nèi)容

(?:)和(?=)的區(qū)別

  • (?:)符合匹配的字符串位置,(?:\d)和\d除了不緩存數(shù)據(jù)外沒其他差別
  • (?=)符合匹配的字符串位置之前
'12345678'.replace(/(?:\d)/g, ','); 在這里等同于 '12345678'.replace(/\d/g,',');
    結(jié)果:",,,,,,,,"
'12345678'.replace(/(?=\d)/g, ',');
    結(jié)果",1,2,3,4,5,6,7,8"

Step2實戰(zhàn)開始:在字符串中查找出所有匹配規(guī)則的字符串

    var str = "changxu is chang + xu , changxu is a boy";
    var patten = /changxu/; //尋找出所有的changxu來
    var result = patten.exec(str);
    console.log(result);
    console.log(patten.lastIndex);

    打印結(jié)果:
    ["changxu", index: 0, input: "changxu is chang + xu , changxu is a boy"]
    0
    
    總結(jié):
    * 只找出了一次观游,但是我們想要找出所有的搂捧,怎么辦?
    * result為一個array結(jié)構(gòu)备典,可以通過result.length 查詢長度异旧。result[0]存放搜索結(jié)果,1~9存放了我們表達(dá)式內(nèi)匹配()的部分
    * result.input:為當(dāng)前執(zhí)行搜索的字符串原型,由于基本沒啥用處提佣,所以下面的案例里面我省略了這個參數(shù)
    * result.index:代表當(dāng)前關(guān)鍵字出現(xiàn)的第一個位置

遺留問題:這里只查到了字符串中第一個changxu吮蛹,如何查到所有的?

利用g參數(shù)來循環(huán)查找我們需要的字符止到結(jié)尾

    var str = "changxu is chang + xu , changxu is a boy";
    var patten = /changxu/g; //尋找出所有的changxu來
    var result = patten.exec(str);
    while( patten.lastIndex != 0  ){//當(dāng)增加了g參數(shù)拌屏,patten.lastIndex才會起效潮针,不然永遠(yuǎn)是0
        result = patten.exec(str);
        console.log(result);
        console.log(patten.lastIndex);
    }
    結(jié)果:
    ["changxu", index: 0]
    7
    ["changxu", index: 24]
    31
    0

既然找到了目標(biāo),那么我們將所有的changxu替換為god

    var str = "changxu is chang + xu , changxu is a boy";
    var patten = /changxu/g; //如果沒g的情況下倚喂,只會替換一次
    var result = str.replace(patten,"god");
    console.log(result);
    console.log(patten.lastIndex);
    結(jié)果:
    god is chang + xu , god is a boy
    0

我們以changxu為目標(biāo)每篷,切割字符串

    var str = "changxu is chang + xu , changxu is a boy";
    var patten = /changxu/; // 這里有g(shù)和無g沒區(qū)別
    var result = str.split(patten);
    console.log(result);
    console.log(patten.lastIndex);
    結(jié)果:
    ["", " is chang + xu , ", " is a boy"]
    0

( ) 的用法

舉個例子:我們搜索一個字符串內(nèi)所有符合在{}之間的字符串瓣戚,并且需要把中間的內(nèi)容取出來

    var str = "{i love you},{i need you},{you love me},you need me";
    var patten = /{i (\w+) you}/g; 
    var result = patten.exec(str);
    console.log(result);
    console.log(patten.lastIndex);
    while( patten.lastIndex != 0  ){
    result = patten.exec(str);
    if( result ) console.log(result);
    console.log(patten.lastIndex);
    }
    結(jié)果:
    ["{i love you}", "love", index: 0]
    12
    ["{i need you}", "need", index: 13]
    25
    0

那么現(xiàn)在如何將這些找出來的字符替換成我們想要的呢?

還是這個例子焦读,我們{ i @key you} 里面的這個@key找出來了子库,那么將@key全部替換為“fuck”怎么做呢?

    var str = "{i love you},{i need you},{you love me},you need me";
    var patten = /{i (\w+) you}/g; 
    var result = str.replace( patten, function(allKey,key1){//如果有多個key那么這里可以增加key2,key3,key4....
          console.log(allKey+'\t'+key1);
        allKey = allKey.replace(key1,"fuck");
        return allKey;
    } );

    console.log(result);
    結(jié)果:
    {i love you} love
    {i need you} need
    {i fuck you},{i fuck you},{you love me},you need me

i參數(shù)忽略大小寫

var patten = /{i (\w+) you}/ig; 

回到最初

  • 取出所有 參數(shù)=值 列表
var str= "?am_id=2&approach=test&type=2&phone=137000";
var result = {};
var temp = null;
var patten = /([^&?]+)=([^&?]+)/g;
temp = patten.exec(str);
if (temp) {result[temp[1]] = temp[2];}
while (patten.lastIndex !== 0) {
    temp = patten.exec(str);
    if (temp) {result[temp[1]] = temp[2];}
}
console.log(result);
  • 查詢type的值矗晃?
var temp = null;
var patten=/[&?]type=([^&?]+)/g;
temp = patten.exec(str);
if(temp){console.log(temp[1]);}

排除字符串

假設(shè)我們要排除字符串中不能有antd字符串仑嗅,我們可以用
/^((?!字符串).)+$/,這里要注意必須帶上^開頭符和$結(jié)尾符,想想為什么张症?

/^((?!antd).)+$/

這個正則圖形化后的邏輯如下圖


image.png

match和exec的區(qū)別

使用方法不一樣

    * match是字符串包裝對象的方法仓技,用法:String.match(RegExp);
    * exec是正則表達(dá)式對象的方法,用法:RegExp.exec(String);
    * match將會把所有查詢到匹配的字符串給放進(jìn)數(shù)組內(nèi)輸出俗他,而exec則需要循環(huán)調(diào)用來達(dá)到獲取所有的匹配

常用正則

  • 將手機號以 xxx xxxx xxxx格式化
var phone='13766778899';
phone = phone.replace(/(\d)(?=(\d{4})+$)/g, '$1 ');
  • 將數(shù)字按貨幣方式以逗號分割 如:1,234,567,890,123
    var money='1234567890123';
    money.replace(/(\d)(?=(\d{3})+)/g, '1,');

  • 新的貨幣切割方式
    console.log(new Intl.NumberFormat().format(123456.3334));

案例對比

var patten = /(\d\d(?:\d\d))/g;
var str = "12345678";

var result = patten.exec(str);
console.log(result);
while(result&&result.index>=0){
    result = patten.exec(str);
    console.log(result);
}
["1234", index: 0, input: "12345678"]
["5678", index: 4, input: "12345678"]



var patten = /(\d\d(?=\d\d)/g;
var str = "12345678";
var result = patten.exec(str);
console.log(result);
while(result&&result.index>=0){
    result = patten.exec(str);
    console.log(result);
}

["12", index: 0, input: "12345678"]
["34", index: 2, input: "12345678"]
["56", index: 4, input: "12345678"]


相關(guān)文章引用及推薦

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末脖捻,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子兆衅,更是在濱河造成了極大的恐慌地沮,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件涯保,死亡現(xiàn)場離奇詭異诉濒,居然都是意外死亡周伦,警方通過查閱死者的電腦和手機夕春,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來专挪,“玉大人及志,你說我怎么就攤上這事≌唬” “怎么了速侈?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長迫卢。 經(jīng)常有香客問我倚搬,道長,這世上最難降的妖魔是什么乾蛤? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任每界,我火速辦了婚禮,結(jié)果婚禮上家卖,老公的妹妹穿的比我還像新娘眨层。我一直安慰自己,他們只是感情好上荡,可當(dāng)我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布趴樱。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪叁征。 梳的紋絲不亂的頭發(fā)上纳账,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天,我揣著相機與錄音捺疼,去河邊找鬼塞祈。 笑死,一個胖子當(dāng)著我的面吹牛帅涂,可吹牛的內(nèi)容都是我干的议薪。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼媳友,長吁一口氣:“原來是場噩夢啊……” “哼斯议!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起醇锚,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤哼御,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后焊唬,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體恋昼,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年赶促,在試婚紗的時候發(fā)現(xiàn)自己被綠了液肌。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡鸥滨,死狀恐怖嗦哆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情婿滓,我是刑警寧澤老速,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站凸主,受9級特大地震影響橘券,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜卿吐,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一旁舰、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧但两,春花似錦鬓梅、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽芥丧。三九已至,卻和暖如春坊罢,著一層夾襖步出監(jiān)牢的瞬間续担,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工活孩, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留物遇,地道東北人。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓憾儒,卻偏偏與公主長得像询兴,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子起趾,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,724評論 2 354

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