正则表达式info¶
前言¶
正则表达式一直是困扰很多程序员的一门技术。作为程序开发者,有必要好好了解一下正则,因为很多问题都可以通过一条简单的正则表达式解决,避免写大量脚本去实现。希望这次分享能帮助大家掌握基础的正则,揭开正则表达式各种符号的神秘面纱,从此走上正则大神之路!
句子¶
常见正则:¶
正则表达式基础
原子是正则表达式的最基本组成单位,而且必须至少要包含一个原子。
| 正则 | 意思 | 说明 |
|---|---|---|
| . | 匹配除换行符以外的任意字符 | 加/s表示所有字符 |
| \d | 匹配一个数字字符 | 等价于 [0-9] |
| \D | 匹配一个非数字字符 | 等价于 [^0-9] |
| \w | 匹配包括下划线的任何单词字符 | 等价于[A-Za-z0-9_] |
| \W | 匹配任何非单词字符 | 等价于[^A-Za-z0-9_] |
| \s | 匹配任何空白字符,包括空格、制表符、换页符等等 | 等价于[\f\n\r\t\v\u000B\u0020\u00A0\u2028\u2029] |
| \S | 匹配任何非空白字符 | 等价于 [^ \f\n\r\t\v] |
| \n | 匹配一个换行符 | 等价于 \x0a 和 \cJ |
| \f | 匹配一个换页符 | 等价于 \x0c 和 \cL |
| \r | 匹配一个回车符 | 等价于 \x0d 和 \cM |
| \t | 匹配一个制表符 | 等价于 \x09 和 \cI |
| \v | 匹配一个垂直制表符 | 等价于 \x0b 和 \cK |
| \xxx | 匹配八进制规定的ASCII编码字符 | 比如[0-9]可写成[\48-\57] |
| \xdd | 匹配十六进制规定的ASCII编码字符 | 比如[0-9]可写成[\x30-\x39] |
| \uxxxx | 匹配十六进制规定的Unicode字符 | 比如[0-9]可写成[\u0030-\u0039] |
[abc],表示a或者b或者c中的任意一个字符; [a-z]、[A-Z]、[0-9],表示小写字母,大写字母,0到9的数字; [a-z]、[A-Z]、[^0-9],表示非小写字母,非大写字母,非0到9的数字;
更多参见基本多语言面(Basic Multilingual Plane,BMP)详细信息 基本多文种平面
分枝条件指的是有几种规则,如果满足其中任意一种规则都应该当成匹配,方法是用|把不同的规则分隔开。
| 正则 | 说明 |
|---|---|
| {m} | 表示前面的原子必须出现m次 |
| {m,} | 表示前面的原子最少出现m次 |
| {m,n} | m要小于n,表示前面出现的原子,最少m次,最多n次,包括m和n次 |
| ? | 等价{0,1}表示其前面的原子可以出现0次或1次,有只能有一次,要么没有 |
| + | 等价{1,}表示其前的原子可以出现1次或多次,不能没有最少要有一个 |
| * | 等价{0,}表示其前的原子可以出现0次、1次、或多次 |
当正则表达式中包含能接受重复的限定符时,通常的行为是匹配尽可能多的字符。
它将会匹配整个字符串。这被称为贪婪匹配。| 代码/语法 | 说明 |
|---|---|
| {n,}? | 重复n次以上,但尽可能少重复 |
| {n,m}? | 重复n到m次,但尽可能少重复 |
| ?? | 重复0次或1次,但尽可能少重复 |
| +? | 重复1次或更多次,但尽可能少重复 |
| *? | 重复任意次,但尽可能少重复 |
位置可以理解为相邻字符之间的位置。咱们可以和空字符串进行类比, 字符的首尾、间隙都可以用空字符串进行连接。
| 符号 | 说明 |
|---|---|
| ^ | 脱字符,有m时是行的开头,无m是字符串的开始 |
| $ | 美元符,有m时是行的末尾,无m是字符串的结束 |
| \b | 单词的边界,具体讲有三点规则:①\w和\W之间的位置 ②^与\w之间的位置 ③\w与$之间的位置 |
| \B | 非单词的边界,与上面相反:①\w与\w之间的位置 ②\W与\W之间的位置 ③^与\W之间的位置 ④\W与$之间的位置 |
| \A | 文本开头 |
| \Z | 文本结尾 |
用小括号来指定子表达式(也叫做分组)。
| 代码/语法 | 说明 |
|---|---|
| (exp) | 匹配exp,并捕获文本到自动命名的组里 |
| (?:exp) | 匹配exp,不捕获匹配的文本,也不给此分组分配组号 |
| (?\<name>exp) | 匹配exp,并捕获文本到名称为name的组里 |
特殊变量名表:¶
| 变量名 | 说明 |
|---|---|
| $$ | 直接量符号,即$字符 |
| $n | 第n个子表达式相匹配的文本,n等于[1-9]。等于RegExp.$n |
| $_ | 正则搜索的字符串。等于RegExp.input |
| $& | 正则最后一次匹配的字符串。等于RegExp.lastMatch |
| $+ | 正则最后一个分组内容。等于RegExp.lastParen |
| $` | 正则匹配子串左侧的文本。等于RegExp.leftContext |
| $’ | 正则匹配子串右侧的文本。等于RegExp.rightContext |
反向引用(回溯引用)¶
使用小括号指定一个子表达式后,默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推(等于RegExp.$n)。你可以使用(?:exp)这样的语法来剥夺一个分组对组号分配的参与权。
正则表达式断言高级¶
当我们想要查找类似\b,^,$那样的一个位置,这个位置应该满足一定的条件(即断言),但这个位置并不包含任何内容,我们称之为
零宽断言。又称之为环视(lookaround)结构。
零宽断言¶
| 代码/语法 | 说明 | 名称 |
|---|---|---|
| x(?=exp)y | 断言y部分能匹配exp,与x无关 | 零宽度正预测先行断言,肯定顺序环视,正向前瞻,正向预查,向前断言 |
| x(?!exp)y | 断言y部分不能匹配exp,与x无关 | 零宽度负预测先行断言,否定顺序环视,负向前瞻,负向预查,向前否定断言 |
| x(?<=exp)y | 断言x部分能匹配exp,且exp从右到左匹配,与y无关。ES7支持 | 零宽度正回顾后行断言,肯定逆序环视,向后断言 |
| x(?<!exp)y | 断言x部分不能匹配exp,且exp从右到左匹配,与y无关。ES7支持 | 零宽度负回顾后发断言,否定逆序环视,向后否定断言 |
后行断言的特点是从右向左匹配,分组编号虽然一样从左到右分配,但引用时必须在编号的左边引用。
字符转义¶
性能¶
核心:减少“回溯”次数,尽快匹配结果:
- 1、尽量使用边界符(^、$、\b、\B等),限定搜索字符串位置
- 2、使用具体的元字符(\d、\w、\s等),少用”.”字符
- 3、多使用确定的量词({n}、{n,m}),少用贪婪匹配
- 4、减少分支,减少“回溯”