正则表达式笔记

333 阅读4分钟

1. 正则表达式介绍和定义

正则表达式 (regular expression)描述了一种字符串匹配模式 (pattern),用来检查一串是否含有某种子串、将匹配的符合条件的子串替换或取出

正则表达式可以通过简单地办法来实现强大的功能:

^[0-9]+abc$

  • ^为匹配输入字符串的开始位置
  • [0-9]+匹配多个数字,[0-9]匹配单个数字,+匹配一个或者多个
  • abc$匹配字母 abc 并以 abc 结尾,$为匹配输入字符串的结束位置

写用户注册表单时,只允许用户名包含字符、数字、下划线和连接字符-,并设置用户名长度,就可以使用一下政府则表达式来设定

^[a-z0-9_-]{3,15}$

以上表达式可以匹配a-z、0-9、_ 和 - 组成的长度为3-15个字符的用户名或密码

构造正则表达式的方法和创建数学表达式的方法一样,也就是用多种元字符与运算符可以将小的表达式结合在一起来创建更大的表达式,正则表达式的组件可以是单个字符、字符集和、字符范围、字符间的选择或者所有这些组件的任意组合

正则表达式由普通字符 (例如a到z) 以及特殊字符 (称为 元字符) 组成的文字模式,模式描述在搜索文本时要匹配的一个活多个字符串

正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配

在 JavaScript 中,正则表达式为 RegExp 对象,有两种方法创建 RegExp 对象,通常情况下使用字面量写法

  • 字面量写法 //

    var ecpression = /pattern/flags
    

    通过//标记包裹,内部写入匹配模式,flags 分为三种模式 g / i / m 这三种模式,g 是 global 缩写,意为全局

    正则创建之后会有一个返回值,通过变量接收

    var str = 'max';
    var p = /max/g;
    console.log(p.test(str)); // true
    if(p.test(str)){
        console.log('输入正确')
    }else{
        console.log('输入错误')
    }
    

    test()检验匹配规则是否符合并返回布尔值

  • 构造函数写法 RegExp

    var str2 = 'maxuan';
    var p1 = new RegExp('max','g');
    console.log(p1.test(str2)); // true
    

2. 元字符

正则表达式在线测试网站:regexr.com

  • . 匹配任意字符

  • ^ $ 位置字符

    ^匹配字符串开始的位置

    $匹配字符串结束的位置

  • \w \W 数字和字母的匹配

    \w 匹配数字和字母 - 匹配结果只包括数字、字母和下划线

    \W 匹配非数字和字母 - 匹配数字、字母、下划线以外的结果(符号)

  • \d \D 数字和非数字的匹配

    \d 只匹配 0-9 之间的数字

    \D 匹配 0-9 数字之外的非数字

  • \s \S 空格和非空格的匹配

    \s 只匹配空格

    \S 匹配空格之外的全部字符

3. 字符集和

  • 字符集合通过 [ ] 包裹,匹配 [ ] 里面的任意字符

    /[a-f]/g — 匹配a b c d e f几个小写字母

    /[a-z]/g — 匹配a-z的所有小写字母

    /[a-zA-Z]/g — 匹配a-z的所有大小写字母

    /[a-zA-Z0-9]/g — 匹配所有字母和数字字符

    /[\u4e00-\u9fa5]/g — 匹配所有中文字符 ( [ ]之中为中文字符的第一个字到最后一个字的Unicode码 )

  • [^ ] 将^写在 [ ] 之内, 表示匹配除 [ ] 内的任意字符

    /[ ^a-z ]/g 匹配除 a-z 的任何字符

4. 重复匹配

允许当前一个字符或字符集匹配的次数

  • + 匹配一次或者多次

    /max+/g 匹配 max 或者 maxxxx

    /ma+x/g 匹配 max 或者 maaaax

    如果想要匹配字符又不区分大小写,可以写成如下,将字母写在字符集和内

    /[mM] [aA] [xX]+/g 可以匹配 MaXXXxxx

  • * 匹配0次或多次

    var regExp = /[a-m]+[!@.#$%^&*()]*/g
    var string = 'ma(!@()#$%^.&*())maaxxxma'
    console.log(regExp.test(string)); // true
    

    允许匹配的字符或集合不存在或者多次重复

  • ? 匹配重复的0次或1次

    /[a-m]+x?[!@.#]*/g 匹配的 x 可以不存在也可以匹配一次

5. 分组匹配

通过 ( ) 对字符进行分组匹配,$序号 来获取对应的值

/(https|http):\/{2}w{3}\.(baidu|google|mi|apeland)\.(com|cn)/g
https://www.baidu.com
http://www.google.com
https://www.mi.com
https://www.apeland.cn

如果想要只做分组匹配,但是不想通过捕获,可以写为(?:httpshttp),这样捕获,可以写为 (?:https|http),这样1获取到的就是第二组了

上方的正则表达式完全匹配下方的网址,通过 ( ) 包裹分组,| 表示或,为避免正则内的元字符错误,需要前面加 \ 写成/ 和 \. 对 / . 进行转义,{ }叫做重复类,内写入数字表示重复指定的次数,如果写两个数字并用 , 隔开表示匹配字符长度范围,

var regExp = /(https|http):\/{2}w{3}\.(baidu|google|mi|apeland)\.(com|cn)/g;
var link = 'https://www.apeland.cn';
regExp.test(link) // true

RegExp.$2 // apeland
image-20200913175030637

通过测试得到结果,第二个打印总是返回 false,正则构造函数$返回的是第一个地址的分组匹配值

6. 预查

预查是匹配符合条件的字符,但是又不包含该字符

6.1 正向预查

/\d+/g

2002000200200
  • 正向肯定预查

    /\d+(?=元)/g
    
    匹配结果:
    2002000

    匹配数字并且带有元的字符,但返回的结果并不包含元这个字符

  • 正向否定预查

    /\d+(?!元)/g
    
    匹配结果:
    20
    200
    200200

    匹配数字并且不带有元的字符,这并不是想要的匹配结果,是因为前两条只匹配到了倒数第二个数字

    这时需要再添加一个匹配条件,这表示预查结果的末尾不包含元和数字,来排除掉不符合预期的结果

    /\d+(?!元|\d)/g
    
    匹配结果:
    200200

6.2 反向预查

/\d+/g

¥2002000
$200
€200
  • 反向肯定预查

    /(?<=¥)\d+/g
    
    匹配结果:
    ¥2002000
    
  • 反向否定预查

    和正向否定预查一样也需要添加末尾不包含数字的匹配条件

    /(?<!¥)\d+/g
    
    匹配结果:
    $200
    €200
    

7. 正则实例对象的方法

  • test() — 返回一个布尔值,表示当前模式是否能匹配字符串

    var reg = /l/g;
    console.log(reg.test('hello')); // true
    
  • exec() — 用来返回匹配的结果的数组,数组中是匹配的子字符串,匹配失败则返回null

    var reg = /l/g;
    console.log(reg.exec('hello')); 
    
    image-20200913212140364
  • match() — 对字符串进行正则匹配,返回匹配结果,匹配失败则返回null

    var reg = /l/g;
    var str = 'hello world';
    
    console.log(str.match(reg)); // ["l", "l", "l"]
    
  • search() — 返回第一个满足条件的匹配结果在整个字符串中的位置,如果没有任何匹配项则返回 -1

    var reg = /l/g;
    var str = 'hello world';
    
    console.log(str.search(reg)); // 2
    
  • replace() — 可以替换匹配的值,它接收两个参数,第一个是正则表达式,表示模式,第二个是替换的内容

    var timeStr = '2020.9.13';
    timeStr.replace(/\./g,'-'); // 2020-9-13
    

需要注意的是,前两个是正则表达式的方法,方法前为正则表达式,方法的参数为字符串

后面三个为字符串的方法,方法前为需要匹配的字符串,方法的参数为正则表达式

8. 正则表达式案例

8.1 检查用户账号

验证规则:由字母、数字、下划线组成,以字母开头的4-16位字符串

function checkUser(str) {
    var reg = /^[a-zA-Z]\w{3,15}$/g;
    if (reg.test(str)) {
        return '格式正确 (√)'
    } else {
        return '格式错误 (×)'
    }
}
checkUser('Max123456_789'); // 格式正确 (√)

注:正则结尾的$用于限制最终字符长度,不可缺少

8.2 验证手机号

验证规则:11位,1开头,第二位 3 5 7 8

function checkMoble(num) {
    var reg = /^1[3|5|7|8]\d{9}$/g
    if (reg.test(num)){
        return '格式正确 (√)'
    }else{
        return '格式错误 (×)'
    }
}
checkMoble(13934588758) // 格式正确 (√)

8.3 验证电话号码

验证规则:区号 + 号码 — 区号开头为0的3到4位数,中间横杠隔开或者不写,后面是7到8位数字

function checkTel(num) {
    var reg = /^0\d{2,3}-?\d{7,8}$/g
    if(reg.test(num)){
        return '格式正确 (√)'
    }else{
        return '格式错误 (×)'
    }
}
checkTel('010-7777777') // 格式正确 (√)

8.4 验证身份证号格式

验证规则:15位或者18位,15位全部为数字,18位的前17位为数字,最后一位可能是x或X

function checkCard(num) {
    var reg = /^\d{15}(\d{2}[\d|x|X])?$/g
    if (reg.test(num)) {
        return '格式正确 (√)'
    } else {
        return '格式错误 (×)'
    }
}
console.log(checkCard("12345678987654512x")); //格式正确 (√)

正则解释为前15位为数字 后3位可以是两位数字加上一位数字或大小写X,也可以没有

8.5 验证邮箱

验证邮箱:邮箱前缀和@地址为数字、字母和下划线,不限长度,以 .com|cn|net|org 结尾

function checkMail(str) {
    var reg = /^\w+@\w+\.(com|cn|net|org)$/g;
    if (reg.test(str)) {
        return '格式正确 (√)'
    } else {
        return '格式错误 (×)'
    }
}
console.log(checkMail('Max2_3475357@qq.com'));