每次都会忘记的正则!

正则表达式

Regular expressions:用来匹配字符串中字符组合的模式.

两种表达方式
  • 字面量(在编译时新建正则表达式,即在代码在如是生成)

    1
    var regex = /xyz/
  • 构造函数,可以接受第二个参数,表示修饰符 (在运行时新建正则表达式,即在代码运行时生成)

    1
    2
    var regex = new RegExp('xyz','i')
    === var regex = /xyz/i
两种语法
  • 正则对象的方法:regex.test(string) 返回布尔值/ regex.exec(string)返回数组
  • 字符串对象的方法:string.match(regex)
正则对象属性和方法

属性:

  • 3个只读属性,都返回布尔值ignoreCase \ global (全局模式,和lastIndex挂钩)\ mulitline
1
2
3
4
5
6
7
var r = /'abc'/igm
r.ignoreCase //true 表示是否设置了该属性
r.global //true
r.multiline //true
--------
r.source //"abc"
r.lastIndex //0
  • source:只读属性,返回正则表达式的字符串形式(不包括反斜杠)
  • lastIndex: (在设置g的前提下)可读写属性,返回下一次开始搜索的位置

方法:

1
2
3
4
5
可以指定搜索位置
var regex = /x/g
var str = 'yxyx'
regex.lastIndex = 4
regex.test(str) //false
  • test():返回布尔值,用来查看正则表达式与指定的字符串是否匹配regexObj.test(str)

    1
    2
    3
    4
    var str = 'hello world'
    var regex = /^h.+o/
    let result = regex.test(str)
    console.log(result) //true
  • exec():返回一个结果数组或者null (与match()方法类似),regexObj.exec('string') 返回的数组将完全匹配成功的文本作为第一项,将正则括号里匹配成功的作为数组填充到后面。(第一项只返回第一个匹配的字符串)

    当正则表达式使用 “g“ 标志时,可以多次执行 exec 方法来查找同一个字符串中的成功匹配。当你这样做时,查找将从正则表达式的 lastIndex属性指定的位置开始(lastIndex属性是在regex正则表达式上的)。(test() 也会更新 lastIndex 属性)

  • match():返回一个array(数组),包含了整个匹配结果以及任何括号捕获的匹配结果 ;如果没有匹配项,则返回null。str.match(regexObject)

    有g修饰:返回一个Array ,它包含所有匹配的子字符串。捕获组不会被返回(即不返回index属性和input属性)。如果没有匹配到,则返回 null 。

    无g修饰:返回的 Array拥有一个额外的 input 属性,该属性包含被解析的原始字符串。另外,还拥有一个 index 属性,该属性表示匹配结果在原字符串中的索引(以0开始)。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    var str = 'For more information, see Chapter 3.4.5.1';
    var re = /see (chapter \d+(\.\d)*)/i;
    var found = str.match(re);
    console.log(found);
    // logs [ 'see Chapter 3.4.5.1',
    // 'Chapter 3.4.5.1',
    // '.1',
    // index: 22,
    // input: 'For more information, see Chapter 3.4.5.1' ]
    // 'see Chapter 3.4.5.1' 是整个匹配。
    // 'Chapter 3.4.5.1' 被'(chapter \d+(\.\d)*)'捕获。
    // '.1' 是被'(\.\d)'捕获的最后一个值。
    // 'index' 属性(22) 是整个匹配从零开始的索引。
    // 'input' 属性是被解析的原始字符串。
字符串对象方法(match(),search(),replace(),split()) , String.indexOf(2) 字符串里是否包含2
  • string.match(regex) ,类似regex.exec(srting),返回数组;没有匹配到返回null。

    如果设置g修饰,那么返回所有匹配结果所组成的数组。对macth()设置lastIndex无效,对exec()方法设置有效

  • string.search(regex): 返回正则表达式在字符串中首次匹配项的索引。否则,返回 -1。

    该方法忽略g修饰。

    1
    2
    'yxyx'.search(/x/)
    //1
  • string.replace(regex) //一般用于敏感词过滤

    字符串对象的replace方法可以替换匹配的值。它接受两个参数,第一个是搜索模式,第二个是替换的内容。

    语法:string.replace(regex|string , newString|function)

    返回值:替换后的新的字符串不改变原字符串

    注:不加g修饰符,就替换第一个匹配成功的值,否则替换所有匹配成功的值。

    1
    2
    3
    'aaa'.replace('a','b') //'baa'
    'aaa'.replace(/a/,'b') //'baa'
    'aaa'.replace(/a/g,'b') //'bbb'

    第二个参数可以是函数,其返回值为替换的字符串,这个函数接受4个参数

    • 匹配的字符串
    • p1,p2…正则表达式括号里的匹配内容(捕获)
    • 匹配到的字符串的起始位置index
    • 原来的字符串
  • string.split(regex)

    split()方法将一个字符串分割成 字符串数组

    语法:str.split([separator[, limit]])

    参数:第一个表示分割规则,第二个是返回的成员最大数

    1
    2
    3
    4
    'a,b,c,d'.split(',',2)
    //['a','b']
    'a,b,c,d'.split()
    //['a,b,c,d']

正则匹配规则

#####字面量字符和元字符

  1. 字面量字符:如/a/匹配a/b/匹配b

    1
    /dog/.test('dog and cat') //true
  2. 元字符:

    • . :匹配除换行符以外的任意字符

    • 位置字符:

      • ^ 表示字符串的开始位置,只能放在开始第一个位置
      • $ 表示字符串的结束位置,只能放在最后一个位置
      1
      /^dog$/.test('dogdog') //false
    • 选择符:| 表示或的意思

      1
      /11|22/.test('91122') //ture
    • 12个转义符:\. ,\^ ,\$ , \| , + , * , \? , \( , \) ,{ , [ , \\(查找\本身)

      用RegExp方法生成的正则对象要用两个\\来转义

    • 特殊字符:\n 换行键\r 回车键\0 匹配null字符

  3. 字符类:[] 在方括号中的表示只要匹配其中一个就可以了

    1
    /[abc]/.test('fuck') //true
    • 脱字符^ :必须写在方括号第一个位置才有用,表示出了字符类中的字符的其他字符

      1
      /[^abc]/.test('fuck') //false

      套路[^] 表示匹配一切字符,区别于包含换行符的.

    • 连字符- :表示连续范围

      1
      2
      3
      4
      [a-z] [A-Z] [0-9]
      [1-31]这个表示 1到3,而非表示1到31
      -----------
      不要出现[A-z],其中会出现其他字符比如\\

      注:字符类的连字符必须在头尾两个字符中间,才有特殊含义,否则就是字面含义。比如,[-9]就表示匹配连字符和9,而不是匹配09

  4. 预定义模式:

    | 简写 | 原型 | 介绍 |
    | :–: | :———–: | :——————- |
    | \d | [0-9] | 匹配0-9之间的任一数字 |
    | \D | [^0-9] | |
    | \w | [A-Za-z0-9] | 匹配任意的字母、数字和下划线 |
    | \W | [^A-Za-z0-9
    ] | |
    | \s | [\t\r\n\v\f] | 匹配空格(包括制表符、空格符、断行符等) |
    | \S | [^\t\r\n\v\f] | |
    | \b | | 匹配词的边界。 |
    | \B | | |

  5. 重复:{} : {n} 表示重复n次

​ {n,} 表示重复>=n次

​ {n,m} 表示重复>=n次且<=m次

  1. 量词符:? 问号表示某个模式出现0次或1次,等同于{0, 1}

    * 星号表示某个模式出现0次或多次,等同于{0,}

    + 加号表示某个模式出现1次或多次,等同于{1,}

  2. 非贪婪模式:一旦条件满足,就不再往下匹配。

    • *?:表示某个模式出现0次或多次,匹配时采用非贪婪模式。

    • +?:表示某个模式出现1次或多次,匹配时采用非贪婪模式。

    • ?? , {n,m}? , {n,}?

      1
      2
      3
      /tom+/.exec('tommm') //[tommm]
      /tom+?/.exec('tommm') //[tom]
      /tom*?/.exec('tommm') //[to]

  3. 修饰符:g(全局),i(忽略大小写),m(修改^和$de行为,可以识别换行符)

    1
    2
    3
    4
    /world$/.test('hello world\n') // false
    /world$/m.test('hello world\nasdsf') // true
    /^b/m.test('a\nb') // true
  4. 匹配组:()捕获

    1
    2
    3
    /tom+/.exec('tommm') //['tommm']
    /(tom)+/.exec('tommm') //['tom','tom']
    /(tom)+/.exec('tomtom') //['tomtom','tom'] 这里表示tom这个词出现1次或多次
    • 在正则表达式内部,可以用\n引用括号匹配的内容,n是从1开始的自然数,表示对应顺序的括号。

      1
      2
      3
      4
      5
      /(.)b(.)\1\2/.exec('abcac')
      //['abcac','a','c']
      ----------------
      /y(..)(.)\2\1/.exec('yabccab')
      //["yabccab", "ab", "c"]
  5. 非捕获组:(?:x),表示不返回改组匹配的内容,即匹配的结果中不计入这个括号。

    1
    2
    var m = 'abc'.match(/(?:.)b(.)/);
    m // ["abc", "c"]
  6. 先行断言(括号里的内容不返回):x(?=y)称为先行断言,x只有在y前面才匹配,y不会被计入返回结果。比如,要匹配后面跟着百分号的数字,可以写成/\d+(?=%)/。先行断言中,括号里的部分是不返回的。

    1
    2
    var m = 'abc'.match(/b(?=c)/);
    m // ["b"]

    现行否定断言:x(?!y)``x只有不在y前面才匹配,y不会被计入返回结果。比如,要匹配后面跟的不是百分号的数字,就要写成/\d+(?!%)/

    1
    2
    /\d+(?!\.)/.exec(3.14)
    //14

补充
  1. str.substring(start , end) 截取字符串 、 str.substr(start,length)
  2. str.search() 相对的是 str.charAt(index) :根据索引返回字符串中对应的