正则一文通
0x000 概述
正则是用来搜索字符串的!!!
正则是用来搜索字符串的!!!
正则是用来搜索字符串的!!!
重要的事儿说三遍,这个是这片文章的结论。
0x001 环境介绍
- 主要示例语言:
javascript
- 实验场地:
Chrome Console
主要函数:
str.match(regexp)
- 示例:
- 参数:
regexp
一个正则表达式对象。如果传入一个非正则表达式对象,则会隐式地使用 new RegExp(obj) 将其转换为一个 RegExp 。如果你未提供任何参数,直接使用 match() ,那么你会得到一个包含空字符串的 Array :[""] 。
以上太官方了,这个参数直接传入一个正则表达式就行了(上图中的栗子2),当然传一个普通的字符串也行(上图中的栗子1),会自动转化的。如示例所见,完成的功能就是在helloworld
字符串中搜索h
字符而已。 - 返回值:
array
如果字符串匹配到了表达式,会返回一个数组,数组的第一项是进行匹配完整的字符串,之后的项是用圆括号捕获的结果。如果没有匹配到,返回null
以上太官方了,匹配到就返回结果数组,没匹配到返回null
,具体的结果视表达式的不同而有区别,现在讲了也感受不到。上面的例子中键0
的返回值就是搜索到的结果。 - 关于该函数详细说明和具体用法,可以查询 MDN,不过现在没有必要就是了。
正则写法:
//
:在两个/
之间写,推荐这种方式,这种方式下,两个/
之间不能什么都不写,因为会发生很神奇的事情--会变成注释符号,导致后面的语法错误...
- 直接写字符串:会自动转化,但是和第一种方式有些微妙的不同,
推荐第一种
- 示例:
- 说明:以下的标题只是我归纳出来的结果,在正则中并不是如此叫法。
0x002 普通字符
实用性技能的学习还是从实际需求出发比较好,在字符串搜索的应用场景中,最常见的需求是啥?就是在字符串中搜索是否包含另一个字符串
。
例如在helloworld
中判断是否有h
,或者是否有hello
,在这种情况下,就使用所有为的普通字符就好了,这种情况下,就起到了和indexOf
一样的功能,所以我们现在我们可以用正则完成在字符串中搜索是否包含另一个字符串
的需求了。
但是如果正则只能做到这样,那还不如直接用indexOf
,还学啥正则,在上面的栗子中,我们所要搜索的字符串是已知的
、确定的
,比如我们知道我们要搜索h
、hello
,这些都是已知的
、确定的
,但是在很多场景中,我们要搜索的是不确定的
、只满足一定规则的
。所以就有了格式校验
。
0x002 替代符
格式校验
通常出现在表单应用中,比如注册需要填写账户和密码,而账户和密码需要满足一定的条件,账户必须是邮箱、密码必须6-16位字母和数字组合等。
这里就出现了对不确定的
、只满足一定规则的
的字符串的搜索,只要有搜索结果,则就校验通过,无结果,校验则不通过。
如何做到呢,那就是替代符
,替代符
可以替代某一种类型的字符,比如数字、字母、回车、换行等等等。
替代符
的格式是普通字符前面加\
,比如\d
、\w
等,为啥要加\
呢,因为不加\
就是普通字符了啊。
- 替代一个数字:
\d
说明:可以完成需求:字符串中是否至少包含一个数字
,这里的数字指的是:01234567890
- 替代一个非数字:
\d
说明:可以完成需求:字符串中是否完全不包含数字
,这里的数字指的是:01234567890
- 替代一个字符:
\w
说明:可以完成的需求:
字符串中是否至少包含一个字符
,这里的字符指的是:1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghjklmnopqrstuvwxyz_
,或者0-9A-Za-z_
- 替代一个非字符:
\w
说明:可以完成的需求是:
字符串是否完全不包含字符
,这里的字符指的是:1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghjklmnopqrstuvwxyz_
,或者0-9A-Za-z_
- 替代一个换行符:
\n
:
说明:可以完成的需求是:字符串是否包含至少一个换行符
- 替代一个制表符:
\t
:
说明:可以完成的需求是:字符串是否包含至少一个制表符
,这里的制表符指的是按Tab
键产生的 - 替代任意一个空白字符:
说明:可以完成的需求是:字符串是否包含至少一个空白字符
,这里的空白字符指的是换行符
、空白符
、制表符
等 替代任意一个非空白字符:
可以完成的需求是:`字符串是否完全不包含空白字符`,这里的空白字符指的是`换行符`、`空白符`、`制表符`等
匹配
\n
之外的任何字符:.
将以上的几种替换符结合起来,我们就可以完成一些比较有意思的事了,比如:
- 是否包含指定长度的数字:
- 密码是否都是字符:
说明:栗子1返回null
说明校验通过了,栗子2返回了搜索结果,说明存在非字符,所以校验不通过。
虽然可以做到这种程度,但是依旧不够,比如我们无法限制长度,或者更精细的控制,比如邮箱格式的限制,匹配连续10000个0等。以[email protected]
为例,可以看出,邮箱的规则大概是
- 开头以多个字母或者数字组成
- 包含
@
符号 @
后面是一个域名。域名又有自己的规则:
- 开头以多个字母或者数字组成
- 包含
.
.
后面以多个字母或者数字组成
邮箱的格式校验已经怎么复杂了,更何况如果我们要限定指定的几个域名呢?所以任重而道远啊,还得接下去学
0x003 数量
我们在0x002中已经可以做到对数量的控制了,即/\d\d\d/
这种形式,但是这种形式是有问题的,如果我们要匹配10000个0
呢,写10000个/d
可不现实,所以这里必须引入新的符号,那就是数量
。
- 匹配前一个表达式0次或者多次:
*
说明:注意,这里说的是表达式,目前先当做字符来理解,意思是匹配o
这个字符0次或者多次 - 匹配子表达式1次或者多次:
+
说明:匹配o
这个字符1次或者多次
3 匹配字表达式0次或者1次:?
![clipboard.png](/img/bVbd8Cu) **说明**:匹配`o`这个字符0次或者1次
- 匹配指定次数:
{n}
,n
为次数
说明:匹配o
这个字符n
次 - 匹配最少几次:
{n,}
,n
为次数
说明:匹配o
这个字符至少n
次 - 匹配最多几次:
{n,m}
,n
为最少的次数,m
为最多的次数
说明:匹配o
这个字符n-m
次
到目前为止,完成了普通字符
、替代符
、数量
,那我们可以做的事情可就多了,比如邮箱格式校验
![clipboard.png](/img/bVbd8El) 但是,依旧存在问题,请看下面 ![clipboard.png](/img/bVbd8Ew) 我们在邮箱前面和后面加了空白符和其他符号,通过了校验,这很明显是我们目前无法解决的,继续往下
0x004 限定
- 指定开头字符:
^
: - 指定结尾:
$
: - 继续邮箱校验:
目前看似没问题,但是如果我们要求只能使用gmail
和qq
登录呢?还得往下啊!
0x005 运算符
- 集合:
[]
:
说明:包含abc
中的任意字符
说明:不包含abc
中的任意字符 - 字符范围:
[a-z]
:
说明:包含a-z0-9
- 或:
|
说明:是否包含a
或者b
0x006 子表达式
字表达式使用()
来表示,()
内为一个整体。
直接上栗子:
- 邮箱验证:
说明:匹配gmail
或者qq
。 - 获取满足某种格式的数据,比如获取文章中的电话号码
说明:其中:1是整个表达式/tel:(\d+)/
的结果,2是子表达式\d+
的结果
在正则中,所有的单个匹配都是子表达式,比如a
、a+
、a{n,m}
等。所以,其实这包含一种递归的思想,所以,所有使用在表达式上的都可以使用在这些之上,比如(ab)+
,可以匹配ababab
。
0x007 总结
正则表达式的作用就是
搜索字符串!!!
搜索字符串!!!
搜索字符串!!!
只不过可以搜索不确定的
、满足某种规则的
的字符串,而这个功能可以引申出多种使用场景
- 字符串搜索
- 格式校验
- 字符串截取