正则表达式是一个很好的工具,但是每次看到正则表达式的语法就看的头大,导致每次都草草的看了下语法,但是实际应用的时候即使是一个很小的问题也不知道该怎么写,以致于每次都是靠百度,自己始终都不会,甚至有点恐惧解除正则。现在想了下应该是起初的时候就不理解正在表达式的用途,不明白什么时候需要用,使用的思路以及一些概念不明。后来看了几篇博客,讲的很清楚,在这里分享给大家,也算再自己巩固下。相关参考文章,写在各节末尾。
一、基本理解
1、正则表达式是匹配模式,要么匹配字符,要么匹配位置。请记住这句话。
2、匹配模式分为:精确匹配和模糊匹配
3、模糊匹配,有两个方向上的“模糊”:横向模糊和纵向模糊。
4、横向模糊指的是:一个正则可匹配的字符串的长度不是固定的,可以是多种情况的。其实现的方式是使用量词。譬如{m,n},表示连续出现最少m次,最多n次。
5、纵向模糊指的是:一个正则匹配的字符串,具体到某一位字符时,它可以不是某个确定的字符,可以有多种可能。其实现的方式是使用字符组。譬如[abc],表示该字符是可以字符“a”、“b”、“c”中的任何一个。
6、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个分组。
7、简写
①字符组是[]的简写
常见的简写形式有了字符组的概念后,一些常见的符号我们也就理解了。因为它们都是系统自带的简写形式。
1、\d就是[0-9]。表示是一位数字。记忆方式:其英文是digit(数字)。
2、\D就是[^0-9]。表示除数字外的任意字符。
3、\w就是[0-9a-zA-Z_]。表示数字、大小写字母和下划线。记忆方式:w是word的简写,也称单词字符。
4、\W是[^0-9a-zA-Z_]。非单词字符。
5、\s是[ \t\v\n\r\f]。表示空白符,包括空格、水平制表符、垂直制表符、换行符、回车符、换页符。记忆方式:s是space character的首字母。
6、\S是[^ \t\v\n\r\f]。 非空白符。.就是 [ ^ \n\r\u2028\u2029]。
7、通配符,表示几乎任意字符。换行符、回车符、行分隔符和段分隔符除外。记忆方式:想想省略号...中的每个点,都可以理解成占位符,表示任何类似的东西。如果要匹配任意字符怎么办?可以使用[\d\D]、[\w\W]、[\s\S]和[^]中任何的一个。
②量词是{}的简写
量词也称重复。掌握{m,n}的准确含义后,只需要记住一些简写形式。
1、{m,} 表示至少出现m次。
2、{m} 等价于{m,m},表示出现m次。
3、? 等价于{0,1},表示出现或者不出现。记忆方式:问号的意思表示,有吗?
4、+ 等价于{1,},表示出现至少一次。记忆方式:加号是追加的意思,得先有一个,然后才考虑追加。
5、* 等价于{0,},表示出现任意次,有可能不出现。记忆方式:看看天上的星星,可能一颗没有,可能零散有几颗,可能数也数不过来。
参考文章:
1、JS正则表达式完整教程(略长)
2、 正则表达式的基本用法
二、基本语法
正则表达式方法:test(),exec()(通过RegExp对象去调用,参数是字符串)
String对象方法:match(),search(),replace(),split()(通过字符串去调用,参数是正则表达式)
//ToDo exec()、match()的区别待整理
参考文章:
1、javascript正则表达式总结(test|match|search|replace|split|exec)
2、 正则表达式中的exec和match方法的区别
三、基本思路
1、明确要验证的规则
2、拆成(取值范围+量词)这样的组合
3、根据正则表达式规则翻译(取值范围+量词)
4、将翻译好的(取值范围+量词)组合进行拼接
参考文章:
四、易混淆点
在学习过程中把(?)相关的符号弄混了,
(?=)(?<=)(?!)(?<!)==》匹配位置
(?:)==>只分组而不捕获