JS正则表达式从入门到够用

如果觉得还有点用,请您给我一个赞!您的赞是我坚持下去的动力

设想我们是否遇到这些问题?

  • 一个url的参数列表
    var str= "?am_id=2&approach=test&type=2&phone=137000";

    • 取出type的值?
    • 替换type的值?
    • 直接删除type这个参数
    • 取出所有符合规则 参数=值 的内容
  • 一个替换字符串的案例
    var str = "{param1} name is {param2}";

    • 将{param1}替换为my,将{param2}替换为changxu ,结果变为了 my name is changxu
    • 将符合规则“{参数名}”格式的字符串,整个替换掉,替换的目标字符串根据"参数名"。
js中正则的使用
  • /正则表达式/.test("字符串");
  • var patt = new RegExp("正则表达式","扩展参数");
    patt.test("字符串")

Step1:常用符号

  • 用于代表位置的
字符 含义
^ 字符串开始位置,也就是第一个字符位置
$ 字符串结尾位置,也就是最后一个字符位置
  • 用于检测匹配的表达式次数,可以称为量词
字符 含义
* 匹配这个符号之前的表达式,任意次数
+ 匹配这个符号之前的表达式,至少1次
? 匹配这个符号之前的表达式,至少0次或者1次,如果?之前的是一个量词描述则代表非贪婪模式尽可能匹配少 '123456'.replace(/\d{2,4}/g,'*')结果为**,而'123456'.replace(/\d{2,4}?/g,'*')结果为***
{n} 匹配这个符号之前的表达式,n次
{n,} 匹配这个符号之前的表达式,至少n次
{n,m} 匹配这个符号之前的表达式,>=n && <=m 次之间
  • 组成表达式需要的参数
字符 含义
. 匹配 \r\n 外的任意字符
x|y 匹配x或者y任意一个,x和y可以是字符也可以是表达式
[xyz] 匹配括号内的任意一个字符
[^xyz] 匹配除了括号内的字符外的字符
[a-z] 匹配a-z之间的任意一个字符
[a-zA-Z] 匹配a-z或A-Z之间的任意一个字符
[0-9] 匹配0-9之间任意一个字符,等价于\d
  • 特殊作用
字符 含义
( ) 将()范围内符合表达式的结果输出到数组内,最多可以存放9组[0]-[9]
(?:表达式)) 不会缓存括号内的数据
(?=表达式)) 符合匹配的字符串位置之前(并且不会缓存括号内的数据)
(?!表达式)) 不匹配表达式的内容

(?:)和(?=)的区别

  • (?:)符合匹配的字符串位置,(?:\d)和\d除了不缓存数据外没其他差别
  • (?=)符合匹配的字符串位置之前
'12345678'.replace(/(?:\d)/g, ','); 在这里等同于 '12345678'.replace(/\d/g,',');
    结果:",,,,,,,,"
'12345678'.replace(/(?=\d)/g, ',');
    结果",1,2,3,4,5,6,7,8"

Step2实战开始:在字符串中查找出所有匹配规则的字符串

    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);

    打印结果:
    ["changxu", index: 0, input: "changxu is chang + xu , changxu is a boy"]
    0
    
    总结:
    * 只找出了一次,但是我们想要找出所有的,怎么办?
    * result为一个array结构,可以通过result.length 查询长度。result[0]存放搜索结果,1~9存放了我们表达式内匹配()的部分
    * result.input:为当前执行搜索的字符串原型,由于基本没啥用处,所以下面的案例里面我省略了这个参数
    * result.index:代表当前关键字出现的第一个位置

遗留问题:这里只查到了字符串中第一个changxu,如何查到所有的?

利用g参数来循环查找我们需要的字符止到结尾

    var str = "changxu is chang + xu , changxu is a boy";
    var patten = /changxu/g; //寻找出所有的changxu来
    var result = patten.exec(str);
    while( patten.lastIndex != 0  ){//当增加了g参数,patten.lastIndex才会起效,不然永远是0
        result = patten.exec(str);
        console.log(result);
        console.log(patten.lastIndex);
    }
    结果:
    ["changxu", index: 0]
    7
    ["changxu", index: 24]
    31
    0

既然找到了目标,那么我们将所有的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);
    结果:
    god is chang + xu , god is a boy
    0

我们以changxu为目标,切割字符串

    var str = "changxu is chang + xu , changxu is a boy";
    var patten = /changxu/; // 这里有g和无g没区别
    var result = str.split(patten);
    console.log(result);
    console.log(patten.lastIndex);
    结果:
    ["", " is chang + xu , ", " is a boy"]
    0

( ) 的用法

举个例子:我们搜索一个字符串内所有符合在{}之间的字符串,并且需要把中间的内容取出来

    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);
    }
    结果:
    ["{i love you}", "love", index: 0]
    12
    ["{i need you}", "need", index: 13]
    25
    0

那么现在如何将这些找出来的字符替换成我们想要的呢?

还是这个例子,我们{ 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);
    结果:
    {i love you} love
    {i need you} need
    {i fuck you},{i fuck you},{you love me},you need me

i参数忽略大小写

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

回到最初

  • 取出所有 参数=值 列表
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]);}

排除字符串

假设我们要排除字符串中不能有antd字符串,我们可以用
/^((?!字符串).)+$/,这里要注意必须带上^开头符和$结尾符,想想为什么?

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

这个正则图形化后的逻辑如下图


image.png

match和exec的区别

使用方法不一样

    * match是字符串包装对象的方法,用法:String.match(RegExp);
    * exec是正则表达式对象的方法,用法:RegExp.exec(String);
    * match将会把所有查询到匹配的字符串给放进数组内输出,而exec则需要循环调用来达到获取所有的匹配

常用正则

  • 将手机号以 xxx xxxx xxxx格式化
var phone='13766778899';
phone = phone.replace(/(\d)(?=(\d{4})+$)/g, '$1 ');
  • 将数字按货币方式以逗号分割 如: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"]


相关文章引用及推荐

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容