Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

RegExp

1. 创建正则的三种方式

  • 字面量模式

    /pattern/attributes
    
    • 例子
      let re = /ab+c/i;
      
    • 注意,最好作为不更改的常量使用,毕竟在迭代中不会重新编译
  • 构造函数

    new RegExp(string, attributes);
    
    • 例子
      let re = new RegExp("ab+c", "i");
      
    • 注意
      • 可作为变量使用,提供了运行时编译
      • 要对字符进行转义表示,即前面加反斜杠\
  • 字面量+构造函数

    new RegExp(/pattern/, attributes);
    
    • 例子
      let re = new RegExp(/ab+c/, "i");
      

2. 包含参数

  • pattern 参数(表格 1)

    元字符含义例子结果
    .匹配除换行符以外的任意单个字符.ar匹配 car 和 par
    [ ]匹配方括号中包含的任意字符[Tt]he[.]匹配 The.和 the.
    [^ ]匹配方括号中不包含的任意字符[^c]ar匹配 par
    (xyz)普通括号,按顺序匹配字符 xyz,可作为子匹配结果
    {n,m }花括号,匹配前面的字符至少 n 次,但是不超过 m 次
    *匹配前面的子表达式 0 或 多次
    +匹配前面的子表达式 1 或 多次
    ?匹配前面的子表达式 0 或 1 次
    ^要求能匹配到行第一个字符,后面的不管
    $要求能匹配到行的最后一个字符,前面的不管
    • 可通过反斜杠\来转义,用来匹配上面这些特殊字符
    • 普通括号内含三种写法
      • (c|p|g)ar
        • 可以匹配 car,par 和 gar
        • 等价于直接用方括号[cpg]ar,带有“或”的意思了
      • (cpg)ar
        • 可以匹配 cpgar
      • (a-c)ar
        • 可以匹配 aar,bar 和 car
  • pattern 参数(表格 2) 元字符 | 含义 | 等价于| 反义元字符(大写) | 等价于

    • | - | - | - | - | - . | 任意一个字符,除了换行符 | 无 | 无 | 无 \w | 任意一个字母或数字或下划线| [a-zA-Z0-9_] | \W | [^\w] \d | 任意一个数字 | [0-9] | \D | [^\d] \s | 任意空白字符,包括空格/制表/换行 | [\t\n\f\r\p{Z}] | \S | [^\s] \b | 任意单词边界,也就是单词和空格间的位置 | 无 |\B | [^\b]

    • 所谓反义元字符,代表非...,也就是对应补集

  • attributes 参数

    • 取值包括如下三种
      • i 忽略大小写
      • g 全局匹配
      • m 多行匹配 希望对每一行单独执行匹配,比如可对定位符^和$有效

3. 对象的三个属性

  • RegExp.global

    • 是否具有标志 g(表示全局匹配),返回 true/false

    • 所谓全局匹配,就是

      • 每执行一次都会记录下匹配到的位置,作为下一次执行的起点
      • 允许找到第一个后再继续找第二个甚至第三个
      • 如果没匹配到,就重置成 0 当作下一次执行的起点
    • 所谓非全局匹配,就是

      • 每执行一次都只会找第一个匹配到的位置,然后下一次执行的起点永远为零
  • RegExp.lastIndex

    • 记录下次匹配执行的起点,要有全局标志 g 才能用此属性,否则非全局下始终默认为 0
  • RegExp.ignoreCase

    • 是否具有标志 i,表示忽略大小写,返回一个整数,表示上一次匹配后第一个字符的位置

4. 对象的三个方法

  • .compile()

    • 用于脚本执行中编译正则表达式
  • .exec(字符串)

    • 检索字符串中,正则表达式的匹配
    • 返回一个结果数组,若没找到匹配则返回 null
      • 结果数组中,存放着单次匹配的详细信息(包括“子匹配结果、index 属性和 input 属性”)
      • 第 0 个元素是相匹配的文本,(可通过[0]来获取)
      • 第 1/2...个元素是子匹配结果,(可通过[1]来获取)
      • 剩余元素是某些属性,(比如 index 可通过["index"]或者.index 来获取)
    • 对于非全局 RegExp,单次 exec 匹配就结束了
    • 非全局可以用 String 对象的 match 方法代替,二者是一样的
    • 对于全局 RegExp,需要一次次调用 exec 匹配,直到返回 null,重置 lastIndex 为 0,才得到全部匹配
    • 全局不想这么麻烦,那就用 String 对象的 match 方法,帮你一口气搞定,但缺点是损失详细信息
  • .test(字符串)

    • 检索字符串是否有地方匹配某个模式
    • 返回 true/false
    • 对于非全局 RegExp
      • 找到有第 1 个就返回 true
    • 对于全局匹配,
      • 可多次调用,每次会从上一次匹配到的地方开始检索
      • 最后直到下一次执行的起点归零,返回 false 表示再也找不到更多

5. 常用正则表达式

// (1)匹配 16 进制颜色值
var regex = /#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})/g;

// (2)匹配日期,如 yyyy-mm-dd 格式
var regex = /^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/;

// (3)匹配 qq 号
var regex = /^[1-9][0-9]{4,10}$/g;

// (4)手机号码正则
var regex = /^1[34578]\d{9}$/g;

// (5)用户名正则
var regex = /^[a-zA-Z\$][a-zA-Z0-9_\$]{4,16}$/;
  • 正整数^\d+$
  • 负整数^-\d+$
  • 电话号码^+?[\d\s]{3,}$
  • 电话代码^+?[\d\s]+(?[\d\s]{10,}$
  • 整数^-?\d+$
  • 用户名^[\w\d_.]{4,16}$
  • 字母数字字符^[a-zA-Z0-9]*$
  • 带空格的字母数字字符^[a-zA-Z0-9 ]*$
  • 密码^(?=^.{6,}$)((?=.*[A-Za-z0-9])(?=.*[A-Z])(?=.*[a-z]))^.*$
  • 电子邮件^([a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4})*$
  • IPv4 地址^((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))*$
  • 小写字母^([a-z])*$
  • 大写字母^([A-Z])*$
  • 网址^(((http|https|ftp):\/\/)?([[a-zA-Z0-9]\-\.])+(\.)([[a-zA-Z0-9]]){2,4}([[a-zA-Z0-9]\/+=%&_\.~?\-]*))*$
  • VISA 信用卡号码^(4[0-9]{12}(?:[0-9]{3})?)*$
  • 日期(MM/DD/YYYY)^(0?[1-9]|1[012])[- /.](0?[1-9]|[12][0-9]|3[01])[- /.](19|20)?[0-9]{2}$
  • 日期(YYYY/MM/DD)^(19|20)?[0-9]{2}[- /.](0?[1-9]|1[012])[- /.](0?[1-9]|[12][0-9]|3[01])$
  • 万事达信用卡号码^(5[1-5][0-9]{14})*$