正则 | 学习笔记


2019/9/7 笔记 软技能

# 断言

表示一个匹配在某些条件下发生。断言包含先行断言、后行断言和条件表达式。

# 先行断言 x(?=y)

  • Lookahead assertion
  • /x(?=y)/
  • 匹配到后面存在 yx
/x(?=y)/.test('xy') // true
/Jack(?=Sprat)/.test('JackSprat') // true

/Jack(?=Sprat|Frost)/.test('JackSprat') // true
/Jack(?=Sprat|Frost)/.test('JackFrost') // true

# 负向先行断言 x(?!y)

  • Negative lookahead assertion
  • /x(?!y)/
  • 匹配到后面不是 yx
// 找到后面不是小数点的数字
'3.124'.match(/\d+(?!\.)/)
// 找到的是 124

# 后行断言 (?<=y)x

  • Lookbehind assertion
  • /(?<=y)x/
  • 匹配到存在于 y 后面的 x
/(?<=y)x/.test('yx') // true
/(?<=Sprat)Jack/.test('SpratJack') // true

/(?<=Sprat|Tom)Jack/.test('SpratJack') // true
/(?<=Sprat|Tom)Jack/.test('TomJack') // true

# 负向后行断言 (?<!y)x

  • Negative Lookbehind assertion
  • /(?<!y)x/
  • 匹配到前面不是 yx
// 找到前面不是小数点的数字
'3.124'.match(/\d+(?!\.)/)
// 找到的是 3

# 边界

表示行和单词的开始和结尾。

# 以开头 ^

  • ^A
  • 匹配以A开头

# 以结尾 $

  • A$
  • 匹配以A结尾

# 单词边界 \b

  • 匹配一个词的边界
'moon'.match(/\bm/) // m
'moon'.match(/oon\b/) // oon
'moon'.match(/\w\b\w/) // null

/\w\b\w/ 将不会匹配到任何内容,因为不可能存在这种情况:一个词有字符跟随同时又没有字符跟随

# 非单词边界 \B

  • 匹配一个非单词边界
'nooday'.match(/\B.../) // ood
'possibly yesterday'.match(/y\B../) // yes

# 字符类别

用于区分不同类型的字符,例如区分字母和数字。

# 单个字符 .

  • 除换行符之外的任何单个字符
'nay, an apple is on the tree'.match(/.n/) // an, on

# 数字 \d & \D

  • /\d/ 匹配一个数字,等价于/[0-9]/
  • /\D/ 匹配一个非数字,等价于/[^0-9]/

# 单字字符 \w & \W

  • /\w/ 匹配一个单字字符(字母、数字或者下划线),等价于/[A-Za-z0-9_]/
  • /\W/ 匹配一个非单字字符,等价于/[^A-Za-z0-9_]/

# 空白字符 \s & \S

  • /\s/ 匹配一个空白字符(空格、制表符、换页符和换行符),等价于/\f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff/
  • /\S/ 匹配一个非空白字符,等价于/[^\f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]/

# 回车符 \r

  • 匹配一个回车符

# 换行符 \n

  • 匹配一个换行符

# 换页符 \f

  • 匹配一个换页符

# 退格 [\b]

  • 匹配一个退格

# NULL \0

  • 匹配 NULL 字符
  • 不要在这后面跟其它小数,因为 \0<digits> 是一个八进制转义序列

# 组和范围

表示表达式字符的分组和范围。

# x|y

  • 匹配 x 或者 y

# [xyz] & [a-c]

  • 一个字符集合
  • 匹配方括号中的任意字符
  • 特殊符号在一个字符集中没有特殊的意义,不必进行转义

# [^xyz] & [^a-c]

  • [xyz] & [a-c] 取反

# (x)

  • 捕获括号
  • 匹配 x 并且记住匹配项
  • /(abc) \1/ 中对 1 进行转义,用于表示被捕获括号匹配的子字符串(这里代表的是abc)
  • 捕获的内容在字符串中的表现形式是 '$1''$2'
'act act'.match(/(\w+) \1/) // 'act act'
'John Smith'.replace(/(\w+)\s(\w+)/, "$2, $1") // 'Smith, John'

# (?:x)

  • 非捕获括号
  • 不记住匹配项

# 量词

表示匹配的字符或表达式的数量

# (0-n) *

  • /x*/
  • 匹配前一个表达式 0 次或多次
  • 等价于 {0,}
'A ghost boooooed'.match(/bo*/) // booooo

# (1-n) +

  • /x+/
  • 匹配前面一个表达式 1 次或者多次
  • 等价于 {1,}

# (0-1) ?

  • /x?/
  • 匹配前面一个表达式 0 次或者 1 次
  • 等价于 {0,1}

# (组合) *? & +?

  • *+ 将会不间断的一直匹配下去(mdn上描述为 greedy 贪婪地)
  • ? 相较来说就是 non-greedy
  • 两者结合则会产生奇妙的效果,可以理解为有节制的贪婪
'some <foo> <bar> new </bar> </foo> thing'.match(/<.*>/) // <foo> <bar> new </bar> </foo>
'some <foo> <bar> new </bar> </foo> thing'.match(/<.*?/) // <
'some <foo> <bar> new </bar> </foo> thing'.match(/<.*+/) // <f
'some <foo> <bar> new </bar> </foo> thing'.match(/<.*?a/) // <foo> <ba

# 使用技巧

# 转义

  • 使用反斜杠 \ ,进行转义
  • 普通字符转义之后变成特殊字符
  • 特殊字符转义之后变成普通字符
  • 反斜杠可以使用反斜杠来转义,识别成普通的反斜杠字符串

# 标志

  • g :全局搜索
  • i :不区分大小写搜索
  • m :多行搜索
  • s :允许 . 匹配换行符
  • u :使用unicode码的模式进行匹配
  • y :执行 “粘性” 搜索,匹配从目标字符串的当前位置开始,可以使用y标志
  • 标志可组合使用
Last Updated: 12/2/2019, 9:23:57 AM