JS-RegExp函数

项目中碰到一些的字符串处置惩罚场景:

  1. 对整型金额举行千分位花样化,如:1,000
  2. 表单字段校验,如姓名只能是中文且长度局限是[2,4]
  3. 身份证号保存前6后4,中心8位掩码处置惩罚。

关于这些都能够运用正则表达式完成。假如你还不知道该怎样用,那有必要进修下正则表达式了。

一、RegExp函数

正则表达式特地用于形貌字符串的字符组合花样。我们常常对字符串推断是不是婚配指定的正则表达式,以及对婚配的字符举行操纵(如替代,转换等)。

1.1 建立正则表达式对象

RegExp用来示意正则表达式。RegExp等于组织函数也是个工场函数。
建立正则表达式的体式格局:

// 字面量体式格局
/pattern/flags

// 组织函数体式格局
new RegExp(pattern [, flags])

// 工场函数体式格局
RegExp(pattern [, flags])

1.2 exec(String)要领

对指定对字符串举行一次正则婚配操纵。假如婚配胜利则返回一个数组,不然返回null。
返回的数组:

  1. 第一个元素是婚配胜利对字符串;
  2. 从第二个元素最先都是婚配的捕捉分组字符串;
  3. 该数组被添加了两个分外属性:
    3.1 input

     示意输入原始字符串,即exec要领的实参。

    3.2 index

     示意婚配的字符串在输入参数的下标位置。
    
// matchs1为["ab", "b", index: 0, input: "abcabc"]
var matchs1 = /a(b)/.exec('abcabc'); // 捕捉分组

// matchs2为["ab", index: 0, input: "abcabc"]
var matchs2 = /ab/.exec('abcabc');

1.3 test(String)要领

推断指定的字符串是不是婚配正则表达式。

1.4 flags(i,g,m)

掌握婚配行动。

1.5 lastIndex属性

示意正则表达式下次实行婚配操纵时字符串下标位置。

var r = /a(b)/g;
console.log(r.lastIndex); // 0
r.test('abcabc'); //true, 从字符串下标0最先婚配
console.log(r.lastIndex); // 2
r.test('abcabc'); //true, 从字符串下标2最先婚配
console.log(r.lastIndex); // 5

注重几点:

  1. 只要指定全局婚配m时,lastIndex才有用,不然一向为0;

    var r = /a(b)/; // 没有指定全局m
    console.log(r.lastIndex); // 0
    r.test('abcabc'); //true, 从字符串下标0最先婚配
    console.log(r.lastIndex); // 0
    r.test('abcabc'); //true, 从字符串下标0最先婚配
    console.log(r.lastIndex); // 0
  2. 每次实行全局形式婚配(经由过程exec或许test要领)时都邑影响lastIndex的值。
    注重下例中屡次挪用会涌现婚配失利的状况:

    var r = /a(b)/g;
    console.log(r.lastIndex); // 0
    r.test('abcabc'); //true, 从字符串下标0最先婚配
    console.log(r.lastIndex); // 2
    r.test('abcabc'); //true, 从字符串下标2最先婚配
    console.log(r.lastIndex); // 5
    r.test('abcabc'); //false, 从字符串下标5最先婚配
    console.log(r.lastIndex); // 0,下次🈶️从头最先婚配了
  3. lastIndex属性是可读写的。

    var r = /a(b)/g;
    console.log(r.lastIndex); // 0
    r.test('abcabc'); //true, 从字符串下标0最先婚配
    console.log(r.lastIndex); // 2
    r.test('abcabc'); //true, 从字符串下标2最先婚配
    console.log(r.lastIndex); // 5
    r.lastIndex = 0; // 修改成0,下次从头最先
    r.test('abcabc'); //true, 从字符串下标0最先婚配
    console.log(r.lastIndex); // 0,下次🈶️从头最先婚配了

二、String中相干的要领

Sting对象的一些要领都接收正则对象的参数:

  1. replace
  2. split
  3. match
  4. search

三、 正则表达式语法

细致的见参考,这里罗列了一些笔记,首先是一张正则学问简图:

《JS-RegExp函数》

  1. 元字符作为平常字符婚配时须要转移;
  2. 除了能够婚配字符外,还能够婚配位置,即图中【位置婚配】部份;
  3. 量词

    • 润饰【字符婚配】,【捕捉分组】,【非捕捉分组】,【前瞻】;
    • 不能润饰【位置婚配】(包括后瞻);但能够包成分组举行婚配。
  4. 【候选】的优先级最低;

3.1 关于【位置婚配】

正则除了能够婚配字符外还能够婚配位置,图中箭头指向的处所:

《JS-RegExp函数》
图片援用《JavaScript正则迷你书》
位置也是有特征的,而且一个位置能够有多个特征,如字符串abc123, 正则表达式/^/,/\b/, /(?=a)/都婚配最左边的位置。除了罕见的位置婚配字符^,$,\b,\B外,前瞻和后瞻也是位置婚配:

形式称号形貌
(?=exp)正向前瞻婚配exp前面的位置
(?!exp)负向前瞻婚配不满足exp前面的位置,即婚配背面不满足expd的位置
(?<=exp)正向后瞻婚配exp背面的位置(ES6支撑)
(?<!exp)负向后瞻婚配不满足exp背面的位置,即婚配前面不是exp的位置(ES6支撑)
'abc123'.replace(/(?=1)/g, '#'); // abc#123, 婚配字符1前面的位置
'abc123'.replace(/(?!1)/g, '#'); // #a#b#c1#2#3#, 婚配不是字符1前面的位置,有多个位置相符请求
'abc123'.replace(/(?<=1)/g, '#'); // abc1#23, 婚配字符1背面的位置
'abc123'.replace(/(?<!1)/g, '#'); // #a#b#c#12#3#, 婚配不是字符1背面的位置

3.2 位置婚配总结

  1. 都是0宽度,不影响lastIndex;
  2. 能够对同一个位置同时举行多个婚配形式,相当于该位置要满足一切的婚配形式。

     /^^hello\b(?!\w)/.test("hello "); // true 

    位置婚配^反复婚配一个位置,相当于一个位置婚配;
    位置婚配\b(?!\w)都是对同一个位置举行婚配,字符b背面的位置等于个单词末端又黑白单词字符(本例是空格字符)的前面

  3. 暗码划定规矩校验题目
    暗码字符集平常是有平安请求的,比方:必需包括数字,大小写字母等。能够运用【位置婚配】:

    // 划定规矩1 = 长度6到15位,必需是数字,字母,下划线,感叹号,中划线
    /^[0-9a-zA-Z_!-]{6,15}$/.test('abc123'); // true,很轻易完成
    
    // 划定规矩2 = 划定规矩1 + 必需包括大写字母
    /(?=.*[A-Z])^[0-9a-zA-Z_!-]{6,15}$/.test('abc123'); // false
    /(?=.*[A-Z])^[0-9a-zA-Z_!-]{6,15}$/.test('abC123'); // true
    
    // 划定规矩3 = 划定规矩2 + 必需包括下划线
    /(?=.*_)(?=.*[A-Z])^[0-9a-zA-Z_!-]{6,15}$/.test('abC123'); // false
    /(?=.*_)(?=.*[A-Z])^[0-9a-zA-Z_!-]{6,15}$/.test('abC123_'); // true

    道理就是经由过程找满足前提的位置来推断目的字符串是不是相符指定的划定规矩。划定规矩2(划定规矩3同理)的正则表达式相当于对肇端位置添加了多个婚配前提。

3.2 回溯

为了推断是不是婚配完成,举行了一些尝试。尝试的副作用就是形成回溯(形成婚配位置倒退的行动)。
回溯会影响机能,写正则只管躲避形成回溯。

四、 项目中的实战

1. 金额花样化,形如:1,000:

  • 碰到的写法1
function reverse(str) {
     return str.split('').reverse().join('');
}
function format(num) {
    return reverse(reverse(num + '').replace(/(\d{3})(?!$)/g, '$1,'));
}
format(123); // '123'
format(1234); // '1,234'
format(12345); // '12,345'
format(123456); // '123,456'
  • 碰到的写法2
function format(num) {
    return (num + '').replace(/(?!^)(?=(\d{3})+$)/g, ',')
}

一个正则搞定!不过也不可否认,庞杂的正则让人难以明白!!!

2. 表单字段校验,如只能是字母和数字,且长度局限[6,18]

// 正则表达式运用了i flag
function validate(str) {
    return /^[a-z0-9]{6,18}$/i.test(str);
}

3. 表单字段校验,如不准予字符反复三次以上

function validate(str) {
    return return /(.)\1{2,}/i.test(str);
}

正则表达式运用了捕捉分组和反向援用

4. 身份证号保存前6后4,中心8位掩码处置惩罚

function mask(idNo) {
    return idNo.replace(/^(\d{6})\d{8}(.+)$/, '$1********$2')
}

5. 推断一个字符串的一切字符是不是都雷同

function validate(str) {
    return /^(.)\1*$/.test(str);
}

6. 银行卡号花样化:每4位添加个空格

function formatId(idNo) {
    return idNo.replace(/(\d{4})(?!$)/g, '$1 '); // 正则相似例1中的*金额花样化*
}

好玩的正则运用场景延续补充ing

参考

  1. MDN RegExp API
  2. 正则语法教程
  3. Online tool to learn, build, and test Regular Expressions
  4. 司徒正美javascript正则表达式 疾速入门
  5. 《JavaScript正则迷你书》
    原文作者:普拉斯
    原文地址: https://segmentfault.com/a/1190000015723611
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞