正则表达式
模糊匹配
-
横向模糊匹配
匹配的字符串长度不是固定的,使用量词实现
-
纵向模糊匹配
匹配的字符不是确定的,使用字符组实现
字符组
[abc],表示匹配一个字符,它可以是 "a"、"b"、"c" 之一
-
范围表示法
[a-z0-9]: 匹配 a 到 z,0 到 9 的字符 -
排除字符组
使用
^表示求反,[^a-z]匹配除了 a 到 z 的字符 -
简写形式
| 字符组 | 具体含义 |
|---|---|
| \d | 表示 [0-9]。表示是一位数字。记忆方式: 其英文是 digit(数字)。 |
| \D | 表示 [^0-9]。表示除数字外的任意字符。 |
| \w | 表示 [0-9a-zA-Z_]。表示数字、大小写字母和下划线。记忆方式:w 是 word 的简写,也称单词字符。 |
| \W | 表示 [^0-9a-zA-Z_]。非单词字符。 |
| \s | 表示 [ \t\v\n\r\f]。表示空白符,包括空格、水平制表符、垂直制表符、换行符、回车符、换页 符。记忆方式:s 是 space 的首字母,空白符的单词是 white space。 |
| \S | 表示 [^ \t\v\n\r\f]。非空白符。 |
| . | 表示 [^\n\r\u2028\u2029]。通配符,表示几乎任意字符。换行符、回车符、行分隔符和段分隔符 除外。记忆方式: 想想省略号 ... 中的每个点,都可以理解成占位符,表示任何类似的东西。 |
量词
量词也称为重复
- 简写形式
| 量词 | 具体含义 |
|---|---|
| {m,} | 表示至少出现 m 次。 |
| {m} | 等价于 {m,m},表示出现 m 次。 |
| ? | 等价于 {0,1},表示出现或者不出现。记忆方式: 问号的意思表示,有吗? |
| + | 等价于 {1,},表示出现至少一次。记忆方式: 加号是追加的意思,得先有一个,然后才考虑追加。 |
| * | 等价于 {0,},表示出现任意次,有可能不出现。记忆方式: 看看天上的星星,可能一颗没有,可能零散有几颗,可能数也数不过来。 |
- 惰性匹配
量词默认匹配模式是贪婪匹配,尽可能多的匹配。在量词后面加上
?可以关闭贪婪匹配模式,尽可能少的匹配
多选分支
一个模式可以实现横向和纵向模糊匹配。而多选分支可以支持多个子模式任选其一
/good|nice/,此正则用来匹配 "good" 或 "nice" 字符。使用管道符 | 分割模式,匹配其中之一
分支结构是惰性的,当前面的匹配上了,后面的就不再尝试了
/good|goodbye/ 当我们用这个正则匹配 "goodbye" 时,只会匹配到 "good"
小结
掌握字符组和量词就能解决大部分常见的情形
位置匹配
位置
位置 (锚) 是相邻字符之间的位置,对于位置的理解,我们可以理解成空字符 ""
比如 "hello" 字符串等价于如下的形式:
"hello" == "" + "h" + "" + "e" + "" + "l" + "" + "l" + "" + "o" + ""也等价于:
"hello" == "" + "" + "hello"
因此,把 /^hello$/ 写成 /^^hello$$$/,是没有任何问题的:
var result = /^^hello$$$/.test("hello")
console.log(result)
// => true甚至可以写成更复杂的:
var result = /(?=he)^^he(?=\w)llo$\b\b$/.test("hello")
console.log(result)
// => true也就是说字符之间的位置,可以写成多个。
锚
| 锚 | 具体含义 |
|---|---|
| ^ | 匹配行的开头 |
| $ | 匹配行的结尾(从结尾开始匹配) |
| \b | 匹配单词的边界(就是\w 和\W 之间的位置,包括 \w 与 ^ 之间的位置,和 \w 与 $ 之间的位置) |
| \B | 匹配非单词的边界 |
| (?=模式) | 匹配模式之前的位置 |
| (?!模式) | 匹配不是这个模式之前的位置 |
括号的作用
分组
/a+/ 匹配连续出现的 "a",而要匹配连续出现的 "ab" 时,需要使用 /(ab)+/
其中括号是提供分组功能,使量词 + 作用于 "ab" 这个整体
分支结构
在多选分支结构 (p1|p2) 中,此处括号的作用也是不言而喻的,提供了分支表达式的所有可能
分组引用 (捕获括号)
当模式被放入括号内,匹配的到结果会被捕获,我们可以使用环境提供的 API 来引用它们
可以使用构造函数的静态属性来引用,
RegExp.$1至$9,$num,代表最近匹配上的第几个捕获组
反向引用
在正则本身里也可以引用分组。引用之前的分组中匹配到的结果。使用
\1至\9
\10代表什么呢?
\10代表引用第十个分组匹配结果,而不是\1 和 0,如果想匹配\1 和 0,可以使用(?:\1)0或者\1(?:0)
- 括号嵌套怎么办?
从外向里,开始匹配分组,最外面的括号为
$1,最里面的括号为$maxNum。例如:
var regex = /^((\d)(\d(\d)))\1\2\3\4$/
var string = "1231231233"
console.log(regex.test(string)) // true
console.log(RegExp.$1) // 123
console.log(RegExp.$2) // 1
console.log(RegExp.$3) // 23
console.log(RegExp.$4) // 3- 引用不存在的分组呢?
如果引用不存在的分组,正则不会报错,只是匹配反向引用的字符本身。
例如 \2,就匹配 "\2"。注意 "\2" 表示对 "2" 进行了转义
- 分组后面有量词会怎样?
分组后面有量词的话,分组最终捕获到的数据是最后一次的匹配
var regex = /(\d)+ \1/
console.log(regex.test("12345 1"))
// => false
console.log(regex.test("12345 5"))
// => true非捕获括号
括号中匹配到的内容都会被捕获,如果只是想要括号最原始的功能,而不需要去引用它。可以使用非捕获括号:
(?: 模式)