Java充电社
专辑
博文
联系我
本人继续续收门徒,亲手指导
正则表达式专题(JS版)
-> 正则表达式的拆分
1、JS正则表达式完整教程
2、正则表达式字符匹配攻略
3、正则表达式位置匹配攻略
4、正则表达式括号的作用
5、正则表达式回溯法原理
6、正则表达式的拆分
7、正则表达式的构建
8、正则表达式编程
9、下载PDF版
上一篇:正则表达式回溯法原理
下一篇:正则表达式的构建
<div style="display:none"></div> 对于一门语言的掌握程度怎么样,可以有两个角度来衡量:读和写。 不仅要求自己能解决问题,还要看懂别人的解决方案。代码是这样,正则表达式也是这样。 正则这门语言跟其他语言有一点不同,它通常就是一大堆字符,而没有所谓“语句”的概念。 如何能正确地把一大串正则拆分成一块一块的,成为了破解“天书”的关键,本章就解决这一问题。 ## 内容包括 1. 结构和操作符 2. 注意要点 3. 案例分析 ## 1. 结构和操作符 编程语言一般都有操作符。只要有操作符,就会出现一个问题。当一大堆操作在一起时,先操作谁,又后操作谁呢?为了不产生歧义,就需要语言本身定义好操作顺序,即所谓的优先级。 而在正则表达式中,操作符都体现在结构中,即由特殊字符和普通字符所代表的一个个特殊整体。 JS正则表达式中,都有哪些结构呢? > 字符字面量、字符组、量词、锚字符、分组、选择分支、反向引用。 具体含义简要回顾如下(如懂,可以略去不看): > **字面量**,匹配一个具体字符,包括不用转义的和需要转义的。比如a匹配字符"a",又比如`\n`匹配换行符,又比如`\.`匹配小数点。 > > **字符组**,匹配一个字符,可以是多种可能之一,比如`[0-9]`,表示匹配一个数字。也有`\d`的简写形式。另外还有反义字符组,表示可以是除了特定字符之外任何一个字符,比如`[^0-9]`,表示一个非数字字符,也有`\D`的简写形式。 > > **量词**,表示一个字符连续出现,比如`a{1,3}`表示“a”字符连续出现3次。另外还有常见的简写形式,比如`a+`表示“a”字符连续出现至少一次。 > > **锚点**,匹配一个位置,而不是字符。比如^匹配字符串的开头,又比如`\b`匹配单词边界,又比如`(?=\d)`表示数字前面的位置。 > > **分组**,用括号表示一个整体,比如`(ab)+`,表示"ab"两个字符连续出现多次,也可以使用非捕获分组`(?:ab)+`。 > > **分支**,多个子表达式多选一,比如`abc|bcd`,表达式匹配"abc"或者"bcd"字符子串。 > > **反向引用**,比如`\2`,表示引用第2个分组。 其中涉及到的操作符有: > 1.转义符 `\` > 2.括号和方括号 `(...)`、`(?:...)`、`(?=...)`、`(?!...)`、`[...]` > 3.量词限定符 `{m}`、`{m,n}`、`{m,}`、`?`、`*`、`+` > 4.位置和序列 `^` 、`$`、 `\元字符`、 `一般字符` > \5. 管道符(竖杠)`|` 上面操作符的优先级从上至下,由高到低。 这里,我们来分析一个正则: `/ab?(c|de*)+|fg/` 1. 由于括号的存在,所以,`(c|de*)`是一个整体结构。 2. 在`(c|de*)`中,注意其中的量词`*`,因此`e*`是一个整体结构。 3. 又因为分支结构“|”优先级最低,因此`c`是一个整体、而`de*`是另一个整体。 4. 同理,整个正则分成了 `a`、`b?`、`(...)+`、`f`、`g`。而由于分支的原因,又可以分成`ab?(c|de*)+`和`fg`这两部分。 希望你没被我绕晕,上面的分析可用其[可视化](https://link.juejin.im?target=http%3A%2F%2Flink.zhihu.com%2F%3Ftarget%3Dhttps%3A%2F%2Fjex.im%2Fregulex%2F%23%21embed%3Dfalse%26flags%3D%26re%3Dab%253F%28c%257Cde%2A%29%252B%257Cfg)形式描述如下: ![](https://itsoku.oss-cn-hangzhou.aliyuncs.com/itsoku/blog/article/175/c5dc2ebc-1c3c-4c81-9fe6-f8652dbe35d4.png) ## 2. 注意要点 关于结构和操作符,还是有几点需要强调: ### 2.1 匹配字符串整体问题 因为是要匹配整个字符串,我们经常会在正则前后中加上锚字符`^`和`$`。 比如要匹配目标字符串"abc"或者"bcd"时,如果一不小心,就会写成`/^abc|bcd$/`。 而位置字符和字符序列优先级要比竖杠高,故其匹配的结构是: ![](https://itsoku.oss-cn-hangzhou.aliyuncs.com/itsoku/blog/article/175/4ab22d44-b485-4c0b-abae-0037377d5c8b.png) 应该修改成: ![](https://itsoku.oss-cn-hangzhou.aliyuncs.com/itsoku/blog/article/175/8d8d6a99-4f46-444d-aead-73631beb132e.png) ### 2.2 量词连缀问题 假设,要匹配这样的字符串: > 1. 每个字符为a、b、c任选其一 > > 2. 字符串的长度是3的倍数 此时正则不能想当然地写成`/^[abc]{3}+$/`,这样会报错,说`+`前面没什么可重复的: ![](https://itsoku.oss-cn-hangzhou.aliyuncs.com/itsoku/blog/article/175/a6208577-12fd-4ee6-b6c6-e29d937a5017.png) 此时要修改成: ![](https://itsoku.oss-cn-hangzhou.aliyuncs.com/itsoku/blog/article/175/dc1112de-293d-482e-82d5-5845d6f90416.png) ### 2.3 元字符转义问题 所谓元字符,就是正则中有特殊含义的字符。 所有结构里,用到的元字符总结如下: > `^ $ . * + ? | \ / ( ) [ ] { } = ! : - ,` 当匹配上面的字符本身时,可以一律转义: ```javascript var string = "^$.*+?|\\/[]{}=!:-,"; var regex = /\^\$\.\*\+\?\|\\\/\[\]\{\}\=\!\:\-\,/; console.log( regex.test(string) ); // => true ``` 其中`string`中的`\`字符也要转义的。 另外,在`string`中,也可以把每个字符转义,当然,转义后的结果仍是本身: ```javascript var string = "^$.*+?|\\/[]{}=!:-,"; var string2 = "\^\$\.\*\+\?\|\\\/\[\]\{\}\=\!\:\-\,"; console.log( string == string2 ); // => true ``` 现在的问题是,是不是每个字符都需要转义呢?否,看情况。 #### 2.3.1 字符组中的元字符 跟字符组相关的元字符有`[]`、`^`、`-`。因此在会引起歧义的地方进行转义。例如开头的`^`必须转义,不然会把整个字符组,看成反义字符组。 ```javascript var string = "^$.*+?|\\/[]{}=!:-,"; var regex = /[\^$.*+?|\\/\[\]{}=!:\-,]/g; console.log( string.match(regex) ); // => ["^", "$", ".", "*", "+", "?", "|", "\", "/", "[", "]", "{", "}", "=", "!", ":", "-", ","] ``` #### 2.3.2 匹配“[abc]”和“{3,5}” 我们知道`[abc]`,是个字符组。如果要匹配字符串"[abc]"时,该怎么办? 可以写成`/\[abc\]/`,也可以写成`/\[abc]/`,测试如下: ```javascript var string = "[abc]"; var regex = /\[abc]/g; console.log( string.match(regex)[0] ); // => "[abc]" ``` 只需要在第一个方括号转义即可,因为后面的方括号构不成字符组,正则不会引发歧义,自然不需要转义。 同理,要匹配字符串"{3,5}",只需要把正则写成`/\{3,5}/`即可。 另外,我们知道量词有简写形式`{m,}`,却没有`{,n}`的情况。虽然后者不构成量词的形式,但此时并不会报错。当然,匹配的字符串也是"{,n}",测试如下: ```javascript var string = "{,3}"; var regex = /{,3}/g; console.log( string.match(regex)[0] ); // => "{,3}" ``` #### 2.3.3 其余情况 比如`=` `!` `:` `-` `,`等符号,只要不在特殊结构中,也不需要转义。 但是,括号需要前后都转义的,如`/\(123\)/`。 至于剩下的`^` `$` `.` `*` `+` `?` `|` `\` `/`等字符,只要不在字符组内,都需要转义的。 ## 3. 案例分析 接下来分析两个例子,一个简单的,一个复杂的。 ### 3.1 身份证 正则表达式是: `/^(\d{15}|\d{17}[\dxX])$/` 因为竖杠“|”,的优先级最低,所以正则分成了两部分`\d{15}`和`\d{17}[\dxX]`。 - `\d{15}`表示15位连续数字。 - `\d{17}[\dxX]`表示17位连续数字,最后一位可以是数字可以大小写字母"x"。 可视化如下: ![](https://itsoku.oss-cn-hangzhou.aliyuncs.com/itsoku/blog/article/175/4f34adce-50a4-4d22-9350-44ad1027428a.png) ### 3.2 IPV4地址 正则表达式是: `/^((0{0,2}\d|0?\d{2}|1\d{2}|2[0-4]\d|25[0-5])\.){3}(0{0,2}\d|0?\d{2}|1\d{2}|2[0-4]\d|25[0-5])$/` 这个正则,看起来非常吓人。但是熟悉优先级后,会立马得出如下的结构: `((...)\.){3}(...)` 上面的两个`(...)`是一样的结构。表示匹配的是3位数字。因此整个结构是 > 3位数.3位数.3位数.3位数 然后再来分析`(...)`: `(0{0,2}\d|0?\d{2}|1\d{2}|2[0-4]\d|25[0-5])(0{0,2}\d|0?\d{2}|1\d{2}|2[0-4]\d|25[0-5])` 它是一个多选结构,分成5个部分: - `0{0,2}\d`,匹配一位数,包括0补齐的。比如,9、09、009; - `0?\d{2}`,匹配两位数,包括0补齐的,也包括一位数; - `1\d{2}`,匹配100到199; - `2[0-4]\d`,匹配200-249; - `25[0-5]`,匹配250-255。 最后来看一下其可视化形式: ![](https://itsoku.oss-cn-hangzhou.aliyuncs.com/itsoku/blog/article/175/39521489-174e-459f-b4de-4fd4bedd678a.png) ## 小结 掌握正则表达式中的优先级后,再看任何正则应该都有信心分析下去了。 至于例子,不一而足,没有写太多。 这里稍微总结一下,竖杠的优先级最低,即最后运算。 只要知道这一点,就能读懂大部分正则。 另外关于元字符转义问题,当自己不确定与否时,尽管去转义,总之是不会错的。 ```html 作者:老姚 链接:https://juejin.im/post/5965943ff265da6c30653879 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 ``` <a style="display:none" target="_blank" href="https://mp.weixin.qq.com/s/_S1DD2JADnXvpexxaBwLLg" style="color:red; font-size:20px; font-weight:bold">继续收门徒,亲手带,月薪 4W 以下的可以来找我</a> ## 最新资料 1. <a href="https://mp.weixin.qq.com/s?__biz=MzkzOTI3Nzc0Mg==&mid=2247484964&idx=2&sn=c81bce2f26015ee0f9632ddc6c67df03&scene=21#wechat_redirect" target="_blank">尚硅谷 Java 学科全套教程(总 207.77GB)</a> 2. <a href="https://mp.weixin.qq.com/s?__biz=MzkwOTAyMTY2NA==&mid=2247484192&idx=1&sn=505f2faaa4cc911f553850667749bcbb&scene=21#wechat_redirect" target="_blank">2021 最新版 Java 微服务学习线路图 + 视频</a> 3. <a href="https://mp.weixin.qq.com/s?__biz=MzkwOTAyMTY2NA==&mid=2247484573&idx=1&sn=7f3d83892186c16c57bc0b99f03f1ffd&scene=21#wechat_redirect" target="_blank">阿里技术大佬整理的《Spring 学习笔记.pdf》</a> 4. <a href="https://mp.weixin.qq.com/s?__biz=MzkwOTAyMTY2NA==&mid=2247484544&idx=2&sn=c1dfe907cfaa5b9ae8e66fc247ccbe84&scene=21#wechat_redirect" target="_blank">阿里大佬的《MySQL 学习笔记高清.pdf》</a> 5. <a href="https://mp.weixin.qq.com/s?__biz=MzkwOTAyMTY2NA==&mid=2247485167&idx=1&sn=48d75c8e93e748235a3547f34921dfb7&scene=21#wechat_redirect" target="_blank">2021 版 java 高并发常见面试题汇总.pdf</a> 6. <a href="https://mp.weixin.qq.com/s?__biz=MzkwOTAyMTY2NA==&mid=2247485664&idx=1&sn=435f9f515a8f881642820d7790ad20ce&scene=21#wechat_redirect" target="_blank">Idea 快捷键大全.pdf</a> ![](https://itsoku.oss-cn-hangzhou.aliyuncs.com/itsoku/blog/article/1/2883e86e-3eff-404a-8943-0066e5e2b454.png)
#custom-toc-container