正则表达式-语法
文章参考自https://yanhaijing.com/javascript/2017/08/06/regexp-syntax/,个人学习记录所用
正则表达式教程——语法
正则就是用有限的符号,表达无限的序列,殆已!
正则表达式的语法一般如下(js),两条斜线中间是正则主体,这部分可以有很多字符组成;i部分是修饰符,i的意思表示忽略大小写
1 | /^abc/i |
简单字符
没有特殊意义的字符都是简单字符,简单字符就代表自身,绝大部分字符都是简单字符,例如:
1 | /abc/ // 匹配 abc |
转义字符
\是转义字符,其后面的字符会代表不同的意思,转义字符主要有三个作用:
是为了匹配不方便显示的特殊字符,比如换行,tab符号等
正则中预先定义了一些代表特殊意义的字符,比如\w等
在正则中某些字符有特殊含义(比如下面说到的),转义字符可以让其显示自身的含义
常用转义字符列表:
符号 | 含义 |
---|---|
\n | 匹配换行符 |
\r | 匹配回车符 |
\t | 匹配制表符,也就是tab键 |
\v | 匹配垂直制表符 |
\x20 | 20是2位16进制数字,代表对应的字符 |
\u002B | 002B是4位16进制数字,代表对应的字符 |
\u002B | 002B是4位16进制数字,代表对应的字符 |
\w | 匹配任何一个字母或者数字或者下划线 |
\w | 匹配任何一个字母或者数字或者下划线 |
\W | 匹配任何一个字母或者数字或者下划线以外的字符 |
\s | 匹配空白字符,如空格,tab等 |
\S | 匹配非空白字符 |
\d | 匹配数字字符,0~9 |
\D | 匹配非数字字符 |
\b | 匹配单词的边界 |
\B | 匹配非单词边界 |
\ | 匹配\本身 |
字符集和
有时我们需要匹配一类字符,字符集可以实现这个功能,字符集的语法用[]分隔,下面的代码能够匹配a或b或c
1 | [abc] |
如果要表示字符很多,可以使用-表示一个范围内的字符,下面两个功能相同
1 | [0123456789] |
在前面添加^,可表示非的意思,下面的代码能够匹配abc之外的任意字符
1 | [^abc] |
其实正则还内置了一些字符集,在上面的转义字符有提到,下面给出内置字符集对应的自定义字符集
. 匹配除了换行符(\n)以外的任意一个字符 = [^\n]
1 | \w = [0-9a-zA-Z_] |
量词
如果我们有三个苹果,我们可以说自己有个3个苹果,也可以说有一个苹果,一个苹果,一个苹果,每种语言都有量词的概念
如果需要匹配多次某个字符,正则也提供了量词的功能,正则中的量词有多个,如?、+、*、{n}、{m,n}、{m,}
1 | {n}匹配n次,比如a{2},匹配aa |
正则默认和人心一样是贪婪的,也就是常说的贪婪模式,凡是表示范围的量词,都优先匹配上限而不是下限
a{1, 3} // 匹配字符串’aaa’的话,会匹配aaa而不是a
有时候这不是我们想要的结果,可以在量词后面加上?,就可以开启非贪婪模式
1 | a{1, 3}? // 匹配字符串'aaa'的话,会匹配a而不是aaa |
字符边界
有时我们会有边界的匹配要求,比如以xxx开头,以xxx结尾
^在[]外表示匹配开头的意思
1 | ^abc // 可以匹配abc,但是不能匹配aabc |
$表示匹配结尾的意思
1 | abc$ // 可以匹配abc,但是不能匹配abcc |
上面提到的\b表示单词的边界
1 | abc\b // 可以匹配 abc ,但是不能匹配 abcc |
选择表达式
有时我们想匹配x或者y,如果x和y是单个字符,可以使用字符集,[abc]可以匹配a或b或c,如果x和y是多个字符,字符集就无能为力了,此时就要用到分组
正则中用|来表示分组,a|b表示匹配a或者b的意思
1 | 123|456|789 // 匹配 123 或 456 或 789 |
分组与引用
分组是正则中非常强大的一个功能,可以让上面提到的量词作用于一组字符,而非单个字符,分组的语法是圆括号包裹(xxx)
1 | (abc){2} // 匹配abcabc |
分组不能放在[]中,分组中还可以使用选择表达式
1 | (123|456){2} // 匹配 123123、456456、123456、456123 |
和分组相关的概念还有一个捕获分组和非捕获分组,分组默认都是捕获的,在分组的(后面添加 ?: 可以让分组变为非捕获分组,非捕获分组可以提高性能和简化逻辑
1 | '123'.match(/(?:123)/) // 返回 ['123'] |
和分组相关的另一个概念是引用,比如在匹配html标签时,通常希望
后面的xxx能够和前面保持一致
引用的语法是\数字,数字代表引用前面第几个捕获分组,注意非捕获分组不能被引用
1 | <([a-z]+)><\/\1> // 可以匹配 `<span></span>` 或 `<div></div>`等 |
预搜索
如果你想匹配xxx前不能是yyy,或者xxx后不能是yyy,那就要用到预搜索
js只支持正向预搜索,也就是xxx后面必须是yyy,或者xxx后面不能是yyy
1 | 1(?=2) // 可以匹配12,不能匹配22 |
修饰符
默认正则是区分大小写,这可能并不是我们想要的,正则提供了修饰符的功能,修复的语法如下
1 | /xxx/gi // 最后面的g和i就是两个修饰符 |
g正则遇到第一个匹配的字符就会结束,加上全局修复符,可以让其匹配到结束
i正则默认是区分大小写的,i可以忽略大小写
m正则默认情况下,^和$只能匹配字符串的开始和结尾,m修饰符可以让^和$匹配行首和行尾,不理解就看例子
1 | /jing$/ // 能够匹配 'yanhaijing,不能匹配 'yanhaijing\n' |
总结
刻意练习,方能游刃有余,知己知彼,方能百战百胜,正则是前端的一个武器,技多不压身
有时我们会遇到特别复杂的正则,有时候可能不太直观,下面推荐一个图形化展示的工具,我们把涉及到的语法罗列一下
1 | /^[a-z]*[^\d]{1,10}?(aaa|bbb)(?:ccc)$/ |
可以看到工具能够更快的帮我们理清头绪