Jacleklm's Blog

正则表达式

2019/10/16

语法

/pattern/flags

flags

  • g:全局匹配;找到所有匹配,而不是在第一个匹配后停止
  • i:忽略大小写
  • m:多行; 将开始和结束字符(^和$)视为在多行上工作(也就是,分别匹配每一行的开始和结束(由 \n 或 \r 分割),而不只是只匹配整个输入字符串的最开始和最末尾处

常用字符类别

  • . :匹配任意单个字符。例如,/.y/ 匹配 “yes make my day” 中的 “my” 和 “ay”,但是不匹配 “yes”
  • \d :匹配任意阿拉伯数字。等价于[0-9]。例如,/\d//[0-9]/ 匹配 “B2 is the suite number.” 中的 ‘2’
  • \D :匹配任意一个不是阿拉伯数字的字符。等价于[^0-9]。例如,/\D//[^0-9]/ 匹配 “B2 is the suite number.” 中的 ‘B’
  • \w :匹配任意来自基本拉丁字母表中的字母数字字符,还包括下划线。例如,/\w/ 匹配 “apple” 中的 ‘a’,”$5.28” 中的 ‘5’ 和 “3D” 中的 ‘3’
  • \W :匹配任意不是基本拉丁字母表中单词(字母数字下划线)字符的字符。例如,/\W/ 匹配 “50%” 中的 ‘%’
  • \s :匹配一个空白符,包括空格、制表符、换页符、换行符
  • \S :匹配一个非空白符
  • \ :按照字面意义解释。例如,* 是一个特殊字符,表示匹配某个字符 0 或多次,如 /a*/ 意味着 0 或多个 “a”。 为了匹配字面意义上的 * ,在它前面加上一个反斜杠,例如,/a\*/匹配 ‘a*’

字符集合

  • [xyz] : 字符集合,匹配集合中的任意一个字符(可以理解为多个 | 连用)。例如,[abcd] 等价于 [a-d],匹配”brisket”中的’b’和”chop”中的’c’.
    1
    2
    3
    4
    5
    // 想匹配字符串"Let's take LeetCode contest" 中的 " Let's "
    var str = "Let's take LeetCode contest"
    console.log(str.match(/\w+/)[0]) // Let
    console.log(str.match(/[\w']+/)[0]) // Let's
    console.log(str.match(/(\w|')+/)[0]) // Let's
  • [^xyz] : 反字符集合

边界

  • ^ : 匹配输入开始。例如,/^A/ 不匹配 “an A” 中的 “A”,但匹配 “An A” 中的 “A”
  • $ : 匹配输入结尾。例如,/t$/ 不匹配 “eater” 中的 “t”,但匹配 “eat” 中的 “t”
  • \b : 匹配一个零宽单词边界(zero-width word boundary),如一个字母与一个空格之间。例如,/\bno/ 匹配 “at noon” 中的 “no”,/ly\b/ 匹配 “possibly yesterday.” 中的 “ly”
  • \B : 匹配一个零宽非单词边界(zero-width non-word boundary),如两个字母之间或两个空格之间.例如,/\Bon/ 匹配 “at noon” 中的 “on”,/ye\B/ 匹配 “possibly yesterday.” 中的 “ye”

分组和反向引用(重要)

  • (x) :捕获括号,匹配 x 并且捕获匹配项,可以说有捕获的功能也有“边界”的功能。例如,/(foo)/ 匹配且捕获 “foo bar.” 中的 “foo”。被匹配的子字符串可以在结果数组的元素 [1], ..., [n] 中找到,或在被定义的 RegExp 对象的属性 $1, ..., $9 中找到,这种$的语法一般只在replace中用.
    PS:注意是从$1开始的,而不是$0
    1
    2
    3
    4
    5
    6
    var re = /(\w+)\s(\w+)/;
    var str = "John Smith";
    var result = re.exec(str)
    var newstr = str.replace(re, "$2, $1");
    console.log(result[0]); // John Smith
    console.log(newstr); // Smith, John
  • \n :n是一个正整数。反向引用,向正则表达式中第 n 个括号(从左开始数)中匹配的子字符串,个人理解(1)是用在有捕获括号的时候,定义$是指向哪个捕获项,就算不写\1也会默认$1是捕获的第一项;(2)可以用这个\1代表第一个捕获项,做一些事,eg. \1+
    1
    2
    3
    var s = 'abcabcabcabc'
    var reg = /^(\w+)\1+$/
    console.log(reg.test(s)) // true
  • (?:x) :匹配 x 不会捕获匹配项。这被称为非捕获括号(non-capturing parentheses)。匹配项不能够从结果数组的元素 [1], ..., [n] 或已被定义的 RegExp 对象的属性 $1, ..., $9 再次访问到。

数量词

  • x* :匹配前面的模式 x 0 或多次。例如,/bo*/ 匹配 “A ghost booooed” 中的 “boooo”,”A bird warbled” 中的 “b”,但是不匹配 “A goat grunted”
  • x+ :匹配前面的模式 x 1 或多次
  • x*? :像上面的 * 和 + 一样匹配前面的模式 x,然而匹配是最小可能匹配。例如,/“.*?”/ 匹配 ‘“foo” “bar”‘ 中的 ‘“foo”‘,而 * 后面没有 ? 时匹配 ‘“foo” “bar”
  • x? : 匹配前面的模式 x 0 或 1 次。例如,/e?le?/ 匹配 “angel” 中的 “el”,”angle” 中的 “le”
  • x(?=y) :只有当 x 后面紧跟着 y 时,才匹配 x。 例如,/Jack(?=Sprat)/ 只有在 ‘Jack’ 后面紧跟着 ‘Sprat’ 时,才会匹配它。/Jack(?=Sprat|Frost)/ 只有在 ‘Jack’ 后面紧跟着 ‘Sprat’ 或 ‘Frost’ 时,才会匹配它。然而,’Sprat’ 或 ‘Frost’ 都不是匹配结果的一部分
  • x(?!y) :只有当 x 后面不是紧跟着 y 时,才匹配 x
  • x|y :匹配x或y

在线正则表达式测试

正则表达式的方法

  • 对RegExp的方法
    • exec() 一个在字符串中执行查找匹配的RegExp方法,它返回一个数组(未匹配到则返回 null)。语法是 regexp.exec(string)
    • test() 一个在字符串中测试是否匹配的RegExp方法,它返回 true 或 false。用于只想知道目标字符串与某个模式是否匹配而不想知文本内容。语法是 regexp.test(string)
  • 对String的方法
    • match() 和exex()其实一毛一样,但语法是string.test(regexp)。一个在字符串中执行查找匹配的String方法,它返回一个数组,在未匹配到时会返回 null
    • matchAll 一个在字符串中执行查找所有匹配的String方法,它返回一个迭代器(iterator)
    • search 一个在字符串中测试匹配的String方法,它返回匹配到的位置索引,或者在失败时返回-1
    • replace 一个在字符串中执行查找匹配的String方法,并且使用替换字符串替换掉匹配到的子字符串
    • split 一个使用正则表达式或者一个固定字符串分隔一个字符串,并将分隔后的子字符串存储到数组中的 String 方法

参考资料
RegExp
正则表达式

CATALOG
  1. 1. 语法
    1. 1.1. flags
    2. 1.2. 常用字符类别
    3. 1.3. 字符集合
    4. 1.4. 边界
    5. 1.5. 分组和反向引用(重要)
    6. 1.6. 数量词
    7. 1.7. 在线正则表达式测试
    8. 1.8. 正则表达式的方法