正则表达式是由普通字符以及特殊字符(称为"元字符")组成的文本模式
正则表达式是一个匹配连续串的规则,即匹配会在每个连续的字符串中进行
普通字符
普通字符包括没有显示指定为元字符的所有可打印和不可打印字符。这包括所有的大写和小写字母、所有数字、所有标点符号和一些其他符号
非打印字符
| 字符 | 描述 | 
|---|---|
| \cx | 匹配由x指明的控制字符。例如,\cM匹配一个control-M或回车符。x的值必须为A-Z或a-z之一。否则,将c视为一个原意的'c'字符 | 
| \t | 匹配一个制表符。等价于\x09和\cl | 
| \n | 匹配一个换行符。等价于\x0a和\cJ | 
| \v | 匹配一个垂直制表符。等价于\x0b和\cK | 
| \f | 匹配一个换页符。等价于\x0c和\cL | 
| \r | 匹配一个回车符。等价于\x0d和\cM | 
| \s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于[\f\n\r\t\v]。注意unicode正则表达式会匹配全角空格符 | 
| \S | 匹配任何非空白字符。等价于\f\n\r\t\v | 
| \d | 匹配数字 | 
| \w | 匹配word(数字、字母) | 
| \W | 匹配非word(数字、字母) | 
特殊字符(元字符)
所谓特殊字符,就是有一些特殊含义的字符,例如”?”,如果要匹配特殊字符,就需要对特殊字符进行转义,例如"\?"
| 字符 | 描述 | 
|---|---|
| $ | 匹配输入字符串的结尾位置。如果设置了RegExp对象的Multiline属性,则$也匹配’\n’或’\r’ | 
| () | 标记一个子表达式的开始和结束位置,子表达式可以提供以后使用 | 
| * | 匹配前面的子表达式零次或多次 | 
| + | 匹配前面的子表达式一次或多次 | 
| . | 匹配除换行符\n之外的任何单字符 | 
| [ | 标记一个中括号表达式的开始 | 
| ? | 匹配前面的子表达式零次或一次,或指明一个非贪婪限定符) | 
| \ | 将下一个字符标记为特殊字符或原意字符,或想活引用,或八进制转义符 | 
| ^ | 匹配输入字符串的开始位置,除非在方括号表达式中使用。当该符号在方括号表达式中使用时,表示不接受方括号表达式中的字符集合 | 
| { | 标记限定符表达式的开始 | 
| | | 指明两项之间的一个选择 | 
举几个🌰:
“?” : 例如colou?r可以匹配color和colour
“*“ : 例如runoo*b可以匹配runob、runoob、runooooob等
“+” : 例如runoo+b可以匹配runoob、runooooob等
(abc|bcd|cde):abc、bcd、cde三者之一均可
限定符
限定符是用来制定正则表达式的一个给定组件必须出现多少次才能满足匹配
| 字符 | 描述 | 
|---|---|
| * | 匹配前面的子表达式零次或多次 | 
| + | 匹配前面的子表达式一次或多次 | 
| ? | 匹配前面的子表达式零次或一次 | 
| {n} | n是一个非负整数,匹配确定的n次 | 
| {n,} | n是一个非负整数,至少匹配n次 | 
| {n,m} | m和n均为非负整数,其中n<=m,最少匹配n次且最多匹配m次,注意在逗号和两个数之间不能有空格 | 
贪婪限定符和非贪婪限定符
贪婪模式:*、+ 和 ? 限定符都被称为“贪心的”,因为它们匹配尽可能多的文本。
非贪婪模式:通过在 *、+ 或 ? 限定符之后放置 ?,该表达式从“贪心”表达式转换为“非贪心”表达式或者最小匹配(即找到第一个满足匹配的就停止)
定位符
定位符能够将正则表达式固定到行首或行尾
| 符号 | 描述 | 
|---|---|
| ^ | 匹配输入字符串开始的位置。如果设置了RegExp对象的Multiline属性,^还会和\n或\r之后的位置匹配 | 
| $ | 匹配输入字符串的结尾位置,如果设置了RegExp对象的Multiline属性,$会与\n或\r之前的位置匹配 | 
| \b | 匹配一个单词边界,即字与空格间的位置 | 
| \B | 非单词边界匹配 | 
不能讲限定符与定位符一起使用,由于在紧靠换行或者单词边界的前面或者后面不能有一个以上位置,因此不允许诸如^*之类的表达式
如果要匹配一行文本开始处的文本,要在正则表达式的开始使用^字符。如果要匹配一行文本结束处的文本,要在正则表达式的结束处使用$字符。^和$可以在一个正则表达式中同时使用,例如:
1  | ^Chapter$  | 
表示从文本开始匹配时和从末尾匹配时都是Chapter,说明该行只有Chapter这几个字符
单词边界是单词和空格之间的位置,非单词边界是任何其他位置。
\b字符位于要匹配的字符串的开始,它在单词的开始处查找匹配项,如果它位于字符串的结尾,他在单词的结尾处查找匹配项。
1  | \bCha  | 
选择
AAA | BBB
匹配 AAA 或者 BBB
引用
引用分组和反向引用
对一个正则表达式或部分模式两边添加圆括号将导致相关匹配到一个临时缓冲区中,所捕获的每个子匹配都按照正则表达式模式中从左到右出现的顺序存储。缓冲区的编号从1开始,最多可以存储99个捕获的子表达式。每个缓冲区都可以使用\n访问,其中n为一个标识特定缓冲区的一位或两位十进制数。
例如:
1  | \b([a-z]+)\1\b  | 
反向引用只能用于之前出现的分组。
反向引用的一个例子:要用正则表达式匹配日期,日期的格式为yyyy-mm-dd、yyyy/mm/dd和yyyy.mm.dd都是合理的,注意后面的分隔符和前面的分隔符要相等。则正则表达式可以写作:
1  | \d{4}(-|/|.)\d{2}\1\d{2}  | 
引用分组中对于括号嵌套的解释
1  | ((\d)(\d(\d)))\1\2\3\4  | 
假如利用上述表达式去匹配如下字符串:“123”
则\1指代的是123
\2指代的是1
\3指代的是23
\4指代的是3
即以左括号出现的顺序为作为编号的顺序。
注意对于\10的解释是编号为10的分组,而不是编号为1的分组然后再跟一个0
引用不存在的分组
因为反向引用是引用前面的分组,但我们在正则表达式里引用了不存在的分组时,此时正则不会报错,只是匹配反向引用的字符本身。例如\2,就匹配”\2”,注意”\2”表示对2进行了转意。
非捕获分组
如果只是想要括号最原始的功能,而不想保存捕获的分组,后续不会进行引用,可以使用非捕获分组(?:)
例如:
1  | (?:ab)+ //用于匹配ababab...  |