1. 正则表达式的创建
1.1 使用字面量来创建正则表达式
let reg = /=\d+/g
reg = /\d+/
在两个 / 之间的字符通常为 元字符 和 字面量字符
而在第二个 / 之后的字符则为 修饰符, 修饰符 可以没有
1.2 通过构造函数 RegExp 来创建正则表达式
let reg = new RegExp("\\d+", g)
reg = new RegExp("abc\\d+")
由于 \ 是转移字符, 所以要用 \\ 来表示 \
new RegExp 的时候, 第一个参数为 元字符 | 字面量字符, 第二个参数为 修饰符
2. 正则表达式的匹配规则
2.1. 字面量字符
大部分字符在正则表达式中, 匹配的就其本身, 如 /abc/ 匹配字符串 abc, /2000/ 匹配字符串 2000.
这样的字符在正则表达式中被称作 字面量字符
let reg = /a/
// 匹配字符 "a"
reg = /1/
// 匹配字符 "1"
2.2. 元字符
除了 字面量字符, 正则表达式更多使用的还是 元字符
元字符 通常都具有特殊的含义
2.2.1 量词类 ? , * , + , {}
?表示上一个表达式出现[0, 1]次, 与{0, 1}同义*表示上一个表达式出现[0, +∞)次, 与{0,}同义+表示上一个表达式出现[1, +∞)次, 与{1,}同义
let reg = /abc?/
// 可以匹配 "abc", "ab". 不能匹配 "abd"
reg = /a*b/
// 可以匹配 "b", "ab", "aaaaab"
reg = /a+b/
// 可以匹配 "aaaabb", "ab". 不能匹配 "b"
2.2.2 位置匹配类 ^ , $
^表示匹配对应字符串的开始$表示匹配对应字符串的结尾
let reg = /^ha*o$/
// 可以匹配以 "h" 为头, 以 "o" 为尾, 中间出现 0 到 多个 "a" 的字符串
// 如 "haao" "ho" 就可以匹配到
// 但若是不以 "h" 为头 或 不以 "o" 为尾, 则无法匹配
// 如 "ahaao", "haaoa", "ahaaoa" 就不能匹配到
2.2.3 常用特殊匹配字符 . , \d , \w , \s , \b , []
-
[]: 通常表示匹配[]中的某一个字符注意: 在
[]中,量词类和位置匹配类的字符没有特殊含义let reg = /[ab12]/ // 匹配 "a", "b", "1", "2" 中的任意一个字符 reg = /[ab+c*d?]/ // 匹配 "a", "b", "+", "c", "*", "d", "?" 中的任意一个字符 -
.: 通常用来匹配 除换行符\n以外的任意字符let reg = /.s/ // 匹配 "this", 结果是 "is"; 匹配 "was", 结果是 "as"; 匹配 " s", 结果是 " s"; 不能匹配 "s" -
\d: 通常用来匹配 数字, 等价于[0-9] -
\w: 通常用来匹配 数字|字母|下划线, 等价于[0-9a-zA-z_] -
\s: 通常用来匹配 空白字符, 等价于[ \f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff] -
\b: 通常用来表示 单词的边界let reg = /\bword\b/g // 匹配 "word theword isaword word" 中第一个和最后一个单词 "word"
2.2.4 特殊的匹配规则 x(?=y) , (?<=y)x , x(?!y) , (?<!y)x
-
x(?=y)先行断言 : 只有当符合
x的表达式后面立即跟着一个符合表达式y的字符串的时候, 才能够匹配let reg = /name=(?=\w+)/ // 可以匹配 "name=saber", 匹配结果是 "name=". 不能匹配 "name=" -
(?<=y)x后行断言 : 只有当符合
x的表达式前面跟着一个符合表达式y的字符串的时候, 才能够进行匹配let reg = /(?<=name=)\w+/ // 可以匹配到 "name=saber" 中的 "saber". 无法匹配 "saber" -
x(?!y)正向否定查找 : 只有当符合
x表达式后面跟着一个不符合表达式y的字符串的时候, 才能够匹配let reg = /name=(?!saber)/ // 可以匹配到 "name=berserker" 中的 "name=". 无法匹配 "name=saber" -
(?<!y)x反向否定查找 : 只有当符合
x表达式前面跟着一个不符合表达式y的字符串的时候, 才能够匹配let reg = /(?<!id=)saber/ // 可以匹配到 "name=saber" 中的 "saber", 无法匹配到 "id=saber"
2.3 修饰符 g , i , m
-
g表示使用该正则表达式进行全局匹配, 在没有使用g时, 正则表达式通常只匹配一个结果let reg = /\dabc/ // 匹配 "0abc1abc2abc3" 的结果为 "0abc" reg = /\dabc/g // 匹配 "0abc1abc2abc3" 的结果为 "0abc", "1abc", "2abc" -
i表示使用该正则表达式时忽略字母大小写 -
m表示使用该正则表达式时可以跨行匹配m修饰符可以对^,$的语义进行修改:-
正则表达式
/^a.*b$/表示对以a开始, 以b结尾的整段字符串进行匹配 -
而
/^a.*b$/m在/^a.*b$/的基础上添加了语义: 匹配整段字符串中第一行以 "a" 开始, 以 "b" 结尾的字符串
let reg = /^a.*c$/m // 对 "abbc\nabdc" 进行匹配, 有 "abbc" reg = /^a[\w\s]*c$/m // 能完整对 "abbc\nabdc" 进行匹配(正则匹配的贪婪性?) reg = /^a[\w\s]*c$/ // 无法匹配 "abc\nabd" (因为字符串并没有以 "c" 结尾), 可以匹配到整个字符串 "acccd\nbdcc" -
2.4 分组捕获
-
()分组, 既可以将()内的内容看作一个表达式, 又可以对符合括号内表达式的结果进行捕获 (即能够获取到与该括号内的表达式所匹配的结果)let reg = /(\d+).(\d+)/ let str = "0.0" str.match(reg) //=> ["0.0", "0", "0", index: 0, input: "0.0", groups: undefined] // 第 0 项是正则匹配的结果, 其余项(以数字为 key)是分组捕获的结果 -
\number\1表示该匹配的结果与第1个分组匹配的结果相同,\2表示该匹配与第2个分组匹配的结果相同...let reg = /(\d+).(\d+)\1\2/ let str = "123.234123234" str.match(reg) //=> ["123.234123234", "123", "234", index: 0, input: "123.234123234", groups: undefined] reg = /(\d+).(\d+)\1\1/ str.match(reg) //=> ["23.23412323", "23", "2341", index: 1, input: "123.234123234", groups: undefined] -
(?:x)匹配但不捕获: 对括号内的表达式
x所匹配的结果不进行捕获let reg = /(\d+).(?:\d+)/ let str = "1.2" str.match(reg) //=> ["1.2", "1", index: 0, input: "1.2", groups: undefined]
2.5 正则匹配的贪婪性
贪婪性指的是: 每次匹配的结果尽可能长
let reg = /\d+/
// 对 "123s" 进行匹配, 匹配到的是 "123"
// 而不是 "1", "2", "3", "12", "23" 中的任意一个
取消正则的贪婪性: 在量词类字符后加上 ?, 则匹配满足最低条件的字符串即止
let reg = /\d+?/
// 表示匹配 1 个数字
reg = /\d*?/
// 表示 1 个数字都不匹配
let reg = /\d??/
// 表示 1 个数字都不匹配
reg = /\d{4,}?/
// 表示匹配 4 个数字