Open yuanyuanbyte opened 2 years ago
本系列的主题是 JavaScript 专题,每期讲解一个技术要点。如果你还不了解各系列内容,文末点击查看全部文章,点我跳转到文末。
如果觉得本系列不错,欢迎 Star,你的支持是我创作分享的最大动力。
正则表达式,对大家来说既熟悉又陌生。熟悉是因为工作中有很多场景能用到,比如手机号、邮箱、密码等规则校验。
陌生则是因为正则表达式看上去就是一堆乱码,且一眼看上去很难看懂匹配规则。有时候在网上去找一个特定规则的正则表达式,搜出来的结果各不相同,执行效果更是不尽人意,想自己去修改,感觉也无从下手。
让我们通过这篇由浅入深的正则表达式教程,简单快速学习正则!!!
正则表达式(Regular Expression)是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符")。
(Regular Expression)
正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。
正则表达式是繁琐的,但它是强大的,学会之后的应用会让你除了提高效率外,会给你带来绝对的成就感。
许多程序设计语言都支持利用正则表达式进行字符串操作。
先看一个实例
以下实例从字符串 str 中找出数字:
str
从字符串 str 中提取数字部分的内容(匹配一次):
var str = "abc123def"; var patt1 = /[0-9]+/; console.log(str.match(patt1))
输出结果:
['123', index: 3, input: 'abc123def', groups: undefined]
match() 方法检索返回一个字符串匹配正则表达式的结果。
match()
重点在于match() 方法的返回值:
附加属性:
如上所述,匹配的结果包含如下所述的附加特性。
groups
undefined
index
input
看完match() 方法的返回值,是不是就搞明白为什么上面实例的输出结果是这么一长串数组了吧:['123', index: 3, input: 'abc123def', groups: undefined]
把上面的实例改为使用g标志:
var str = "abc123def"; var patt1 = /[0-9]+/g; console.log(str.match(patt1))
['123']
test() 方法用于检测一个字符串是否匹配某个模式.
test()
如果字符串中有匹配的值返回 true ,否则返回 false。
true
false
语法:RegExpObject.test(string)
RegExpObject.test(string)
var str="Hello world!"; //查找"Hello" var patt=/Hello/g; var result=patt.test(str); console.log("返回值: " + result); // 返回值: true //查找 "Runoob" patt=/Runoob/g; result=patt.test(str); console.log("返回值: " + result);// 返回值: false
通过一个实例学习基本的正则表达式语法
前面的例子是匹配字符串里的单词,现在我们来看一下如何匹配以某规则开头的字符串,以某规则结尾的字符串,以及整个字符串(即是不是 完全以某规则开头,某规则结尾的字符串)
(即是不是 完全以某规则开头,某规则结尾的字符串)
匹配以数字开头,并以 abc 结尾的字符串。:
abc
var str = "123abc"; var patt1 = /^[0-9]+abc$/g; console.log(str.match(patt1))
['123abc']
这里用到了一些基本的匹配规则:
^ 表示必须匹配以^后面规则开头的字符串,如果该字符串不是以^后面的规则开头的,则直接返回null
^
如果该字符串不是以^后面的规则开头的,则直接返回null
$ 表示必须匹配以$前面规则结尾的字符串,如果该字符串不是以$前面规则结尾,则直接放回null
$
如果该字符串不是以$前面规则结尾,则直接放回null
[0-9]+匹配多个数字, [0-9] 匹配单个数字,+ 匹配一个或者多个。
[0-9]+
[0-9]
+
abc$匹配字母 abc 并以 abc 结尾
abc$
总结:
null
通过修改上面的实例,验证一下我们总结的规则:
◾ 单独使用^表示匹配以该规则开头的字符串:
var str = "123abc范德萨发撒1112范德萨发撒"; var patt1 = /^[0-9]+abc/g; console.log(str.match(patt1)) // ['123abc']
◾ 单独使用$表示匹配以该规则结尾的字符串:
var str = "123abc范德萨发撒1112范德萨发撒"; var patt1 = /[0-9]+abc$/g; console.log(str.match(patt1)) // null
上面的字符串没有以[0-9]+abc结尾,所以匹配失败返回null;
[0-9]+abc
var str = "fdsdfds123abc"; var patt1 = /[0-9]+abc$/g; console.log(str.match(patt1)) // ['123abc']
上面的字符串以[0-9]+abc结尾,所以返回匹配结果;
◾ 同时使用^和$则表示整个字符串从开头到结尾必须符合匹配规则才算匹配成功,否则匹配失败返回null:
匹配失败的例子:
var str = "fff123abc"; var patt1 = /^[0-9]+abc$/g; console.log(str.match(patt1)) // null
var str = "123abcfff"; var patt1 = /^[0-9]+abc$/g; console.log(str.match(patt1)) // null
var str = "fsd123abcfff"; var patt1 = /^[0-9]+abc$/g; console.log(str.match(patt1)) // null
var str = "fsd123ddabcfff"; var patt1 = /^[0-9]+abc$/g; console.log(str.match(patt1)) // null
匹配成功的例子:
var str = "123abc"; var patt1 = /^[0-9]+abc$/g; console.log(str.match(patt1)) // ['123abc']
var str = "12321554532532525abc"; var patt1 = /^[0-9]+abc$/g; console.log(str.match(patt1)) // ['12321554532532525abc']
限定符 *、+、?、{n}、{n,} 和 {n,m} 的使用
*、+、?、{n}、{n,} 和 {n,m}
例如:
runoo+b,可以匹配 runoob、runooob、runoooooob 等,+ 号代表前面的字符必须至少出现一次(1次或多次)。
runoo+b
runoo*b,可以匹配 runob、runoob、runoooooob 等,* 号代表前面的字符可以不出现,也可以出现一次或者多次(0次、或1次、或多次)。
runoo*b
colou?r,可以匹配 color 或者 colour,? 问号代表前面的字符最多只可以出现一次(0次、或1次)。
colou?r
*限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有 `或+或?或{n}或{n,}或{n,m}` 共6种。**
或
*
?
{n}
{n,}
普通字符包括没有显式指定为元字符的所有可打印和不可打印字符。这包括所有大写和小写字母、所有数字、所有标点符号和一些其他符号。
[ABC]
[^ABC]
[A-Z]
.
[\s\S]
\w
以下正则表达式匹配一个正整数,[1-9]设置第一个数字不是 0,[0-9]* 表示任意多个数字:
/[1-9][0-9]*/
请注意,限定符出现在范围表达式之后。因此,它应用于整个范围表达式,在本例中,只指定从 0 到 9 的数字(包括 0 和 9)。
这里不使用 + 限定符,因为在第二个位置或后面的位置不一定需要有一个数字。也不使用 ? 字符,因为使用 ? 会将整数限制到只有两位数。
如果你想设置 0~99 的两位数,可以使用下面的表达式来至少指定一位但至多两位数字。
/[0-9]{1,2}/
上面的表达式的缺点是,只能匹配两位数字,而且可以匹配 0、00、01、10 99 的章节编号仍只匹配开头两位数字。
改进下,匹配 1~99 的正整数表达式如下:
/[1-9][0-9]?/
/[1-9][0-9]{0,1}/
❗ ❗ ❗ 重点
*`和+限定符都是贪婪的,因为它们会尽可能多的匹配文字,只有在它们的后面加上一个?` 就可以实现非贪婪或最小匹配。**
和
限定符都是贪婪的,因为它们会尽可能多的匹配文字,只有在它们的后面加上一个
例如,您可能搜索 HTML 文档,以查找在 h1 标签内的内容。HTML 代码如下:
<h1>RUNOOB-菜鸟教程</h1>
贪婪:下面的表达式匹配从开始小于符号 (<) 到关闭 h1 标记的大于符号 (>) 之间的所有内容。
/<.*>/
非贪婪:如果您只需要匹配开始和结束 h1 标签,下面的非贪婪表达式只匹配 <h1>。
<h1>
/<.*?>/
也可以使用以下正则表达式来匹配 h1 标签,表达式则是:
/<\w+?>/
*通过在 `、+ 或 ?限定符之后放置?,该表达式从"贪婪"表达式转换为"非贪婪"`表达式或者最小匹配。**
限定符之后放置
,该表达式从
表达式转换为
所谓特殊字符,就是一些有特殊含义的字符。
(不包括前文讲到的)
\$
()
\( 和 \)
\+
\.
[
\[
\?
\
'\\'
"\"
'\('
\^
{
\{
|
\|
❗ ❗ ❗ 注意:^ 有两种意义
前文已经详细介绍过
"\("
"(.|\n)"
x|y
'z|food'
'(z|f)ood'
正则表达式从左到右进行计算,并遵循优先级顺序,这与算术表达式非常类似。
相同优先级的从左到右进行运算,不同优先级的运算先高后低。下表从最高到最低说明了各种正则表达式运算符的优先级顺序:
(), (?:), (?=), []
*, +, ?, {n}, {n,}, {n,m}
^, $, \任何元字符、任何字符
"m|food"
"(m|f)ood"
🔶 常见的特殊需求
◾ 最新的手机号匹配规则
手机号的正则算是最常用的。常见的手机号正则有 /^1[3456789]\d{9}$/、/^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\d{8}$/
/^1[3456789]\d{9}$/
^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\d{8}$/
根据运营商的最新号段,写出手机号验证的最新正则表达式:
/^1(3\d|4[5-9]|5[0-35-9]|6[567]|7[0-8]|8\d|9[0-35-9])\d{8}$/
◾ 身份证号(15位、18位数字),最后一位是校验位,可能为数字或字符X
身份证号码验证,包含两代身份证,第一代和第二代身份证
第一代身份证15位,其编码规则顺序从左至右依次为6位数字地址码,6位数字出生年份后两位及日期,3位数字顺序码。
第二代身份证18位,其编码规则顺序从左至右依次为6位数字地址码,8位数字出生年份日期码,3位数字顺序码,1位数字校验码(X有时会出现):
以北京市朝阳区一女性身份证号码为例,身份证号码所表示的含义如下图所示:
综上,身份证的正则表达式为:
(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)
◾ 匹配 16 进制颜色值:/#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})/g;
/#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})/g;
◾ 匹配日期,如 yyyy-mm-dd 格式
/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/;
◾ 腾讯QQ号:[1-9][0-9]{4,} (腾讯QQ号从10000开始)
[1-9][0-9]{4,}
◾ 中国邮政编码:[1-9]\d{5}(?!\d) (中国邮政编码为6位数字)
[1-9]\d{5}(?!\d)
◾ Email地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
◾ 帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):
^[a-zA-Z][a-zA-Z0-9_]{4,15}$
◾ 密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线):
^[a-zA-Z]\w{5,17}$
◾ 强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在 8-10 之间):
^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[a-zA-Z0-9]{8,10}$
**◾ 强密码(必须包含大小写字母和数字的组合,可以使用特殊字符,长度在8-10之间):**
^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$
🔶 校验数字
^[0-9]*$
^\d{n}$
^\d{n,}$
^\d{m,n}$
^(0|[1-9][0-9]*)$
^(\-|\+)?\d+(\.\d+)?$
^[0-9]+(\.[0-9]{2})?$
^[0-9]+(\.[0-9]{1,3})?$
^[1-9]\d*$ 或 ^([1-9][0-9]*){1,3}$ 或 ^\+?[1-9][0-9]*$
^\-[1-9][]0-9"*$ 或 ^-[1-9]\d*$
🔶 校验字符
^[\u4e00-\u9fa5]{0,}$
^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$
^.{3,20}$
^[A-Za-z]+$
^[A-Z]+$
^[a-z]+$
^[A-Za-z0-9]+$
^\w+$ 或 ^\w{3,20}$
^[\u4E00-\u9FA5A-Za-z0-9_]+$
^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$
^%&',;=?$\"
[^%&',;=?$\x22]+
[^~\x22]+
查看原文
查看全部文章
各系列文章汇总:https://github.com/yuanyuanbyte/Blog
我是圆圆,一名深耕于前端开发的攻城狮。
本系列的主题是 JavaScript 专题,每期讲解一个技术要点。如果你还不了解各系列内容,文末点击查看全部文章,点我跳转到文末。
如果觉得本系列不错,欢迎 Star,你的支持是我创作分享的最大动力。
由浅入深的正则表达式教程,简单快速学习正则
前言
正则表达式,对大家来说既熟悉又陌生。熟悉是因为工作中有很多场景能用到,比如手机号、邮箱、密码等规则校验。
陌生则是因为正则表达式看上去就是一堆乱码,且一眼看上去很难看懂匹配规则。有时候在网上去找一个特定规则的正则表达式,搜出来的结果各不相同,执行效果更是不尽人意,想自己去修改,感觉也无从下手。
让我们通过这篇由浅入深的正则表达式教程,简单快速学习正则!!!
正则表达式是什么
正则表达式
(Regular Expression)
是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符")。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。
正则表达式是繁琐的,但它是强大的,学会之后的应用会让你除了提高效率外,会给你带来绝对的成就感。
许多程序设计语言都支持利用正则表达式进行字符串操作。
字符串匹配方法 match()
先看一个实例
以下实例从字符串
str
中找出数字:从字符串 str 中提取数字部分的内容(匹配一次):
输出结果:
match()
方法检索返回一个字符串匹配正则表达式的结果。重点在于
match()
方法的返回值:附加属性:
如上所述,匹配的结果包含如下所述的附加特性。
groups
: 一个捕获组数组 或undefined
(如果没有定义命名捕获组)。index
: 匹配的结果的开始位置input
: 搜索的字符串.看完
match()
方法的返回值,是不是就搞明白为什么上面实例的输出结果是这么一长串数组了吧:['123', index: 3, input: 'abc123def', groups: undefined]
把上面的实例改为使用g标志:
输出结果:
字符串检查方法 test()
test()
方法用于检测一个字符串是否匹配某个模式.如果字符串中有匹配的值返回
true
,否则返回false
。语法:
RegExpObject.test(string)
正则表达式语法
^ 和 $ 的用法和区别详解
通过一个实例学习基本的正则表达式语法
前面的例子是匹配字符串里的单词,现在我们来看一下如何匹配以某规则开头的字符串,以某规则结尾的字符串,以及整个字符串
(即是不是 完全以某规则开头,某规则结尾的字符串)
匹配以数字开头,并以
abc
结尾的字符串。:输出结果:
这里用到了一些基本的匹配规则:
^
表示必须匹配以^
后面规则开头的字符串,如果该字符串不是以^后面的规则开头的,则直接返回null
$
表示必须匹配以$
前面规则结尾的字符串,如果该字符串不是以$前面规则结尾,则直接放回null
[0-9]+
匹配多个数字,[0-9]
匹配单个数字,+
匹配一个或者多个。abc$
匹配字母abc
并以abc
结尾总结:
^
表示匹配以该规则开头的字符串;$
表示匹配以该规则结尾的字符串;^
和$
则表示整个字符串从开头到结尾必须符合匹配规则才算匹配成功,否则匹配失败返回null
通过修改上面的实例,验证一下我们总结的规则:
◾ 单独使用
^
表示匹配以该规则开头的字符串:◾ 单独使用
$
表示匹配以该规则结尾的字符串:上面的字符串没有以
[0-9]+abc
结尾,所以匹配失败返回null;上面的字符串以
[0-9]+abc
结尾,所以返回匹配结果;◾ 同时使用
^
和$
则表示整个字符串从开头到结尾必须符合匹配规则才算匹配成功,否则匹配失败返回null
:匹配失败的例子:
匹配成功的例子:
限定符
限定符
*、+、?、{n}、{n,} 和 {n,m}
的使用例如:
runoo+b
,可以匹配 runoob、runooob、runoooooob 等,+ 号代表前面的字符必须至少出现一次(1次或多次)。runoo*b
,可以匹配 runob、runoob、runoooooob 等,* 号代表前面的字符可以不出现,也可以出现一次或者多次(0次、或1次、或多次)。colou?r
,可以匹配 color 或者 colour,? 问号代表前面的字符最多只可以出现一次(0次、或1次)。*限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有 `
或
+或
?或
{n}或
{n,}或
{n,m}` 共6种。***
+
?
{n}
{n,}
普通字符
普通字符包括没有显式指定为元字符的所有可打印和不可打印字符。这包括所有大写和小写字母、所有数字、所有标点符号和一些其他符号。
[ABC]
[^ABC]
[A-Z]
.
[\s\S]
\w
以下正则表达式匹配一个正整数,[1-9]设置第一个数字不是 0,[0-9]* 表示任意多个数字:
请注意,限定符出现在范围表达式之后。因此,它应用于整个范围表达式,在本例中,只指定从 0 到 9 的数字(包括 0 和 9)。
这里不使用 + 限定符,因为在第二个位置或后面的位置不一定需要有一个数字。也不使用 ? 字符,因为使用 ? 会将整数限制到只有两位数。
如果你想设置 0~99 的两位数,可以使用下面的表达式来至少指定一位但至多两位数字。
上面的表达式的缺点是,只能匹配两位数字,而且可以匹配 0、00、01、10 99 的章节编号仍只匹配开头两位数字。
改进下,匹配 1~99 的正整数表达式如下:
或
❗ ❗ ❗ 重点
*`
和
+限定符都是贪婪的,因为它们会尽可能多的匹配文字,只有在它们的后面加上一个
?` 就可以实现非贪婪或最小匹配。**例如,您可能搜索 HTML 文档,以查找在 h1 标签内的内容。HTML 代码如下:
贪婪:下面的表达式匹配从开始小于符号 (<) 到关闭 h1 标记的大于符号 (>) 之间的所有内容。
非贪婪:如果您只需要匹配开始和结束 h1 标签,下面的非贪婪表达式只匹配
<h1>
。也可以使用以下正则表达式来匹配 h1 标签,表达式则是:
*通过在 `、+ 或 ?
限定符之后放置
?,该表达式从
"贪婪"表达式转换为
"非贪婪"`表达式或者最小匹配。**特殊字符
所谓特殊字符,就是一些有特殊含义的字符。
(不包括前文讲到的)
: 字符$
\$
。()
\( 和 \)
。*
+
\+
。.
\.
。[
\[
。?
\?
。\
'\\'
匹配"\"
,而'\('
则匹配 "("。^
\^
。{
\{
。|
\|
。❗ ❗ ❗ 注意:
^
有两种意义前文已经详细介绍过
元字符
\
'\\'
匹配"\"
而"\("
则匹配 "("。^
$
*
+
?
.
"(.|\n)"
的模式。x|y
'z|food'
能匹配 "z" 或 "food"。'(z|f)ood'
则匹配 "zood" 或 "food"。运算符优先级
正则表达式从左到右进行计算,并遵循优先级顺序,这与算术表达式非常类似。
相同优先级的从左到右进行运算,不同优先级的运算先高后低。下表从最高到最低说明了各种正则表达式运算符的优先级顺序:
\
(), (?:), (?=), []
*, +, ?, {n}, {n,}, {n,m}
^, $, \任何元字符、任何字符
|
"m|food"
匹配"m"或"food"。若要匹配"mood"或"food",请使用括号创建子表达式,从而产生"(m|f)ood"
。常用的正则表达式
🔶 常见的特殊需求
◾ 最新的手机号匹配规则
手机号的正则算是最常用的。常见的手机号正则有
/^1[3456789]\d{9}$/
、/^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\d{8}$/
根据运营商的最新号段,写出手机号验证的最新正则表达式:
◾ 身份证号(15位、18位数字),最后一位是校验位,可能为数字或字符X
身份证号码验证,包含两代身份证,第一代和第二代身份证
第一代身份证15位,其编码规则顺序从左至右依次为6位数字地址码,6位数字出生年份后两位及日期,3位数字顺序码。
第二代身份证18位,其编码规则顺序从左至右依次为6位数字地址码,8位数字出生年份日期码,3位数字顺序码,1位数字校验码(X有时会出现):
以北京市朝阳区一女性身份证号码为例,身份证号码所表示的含义如下图所示:
综上,身份证的正则表达式为:
◾ 匹配 16 进制颜色值:
/#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})/g;
◾ 匹配日期,如 yyyy-mm-dd 格式
◾ 腾讯QQ号:
[1-9][0-9]{4,}
(腾讯QQ号从10000开始)◾ 中国邮政编码:
[1-9]\d{5}(?!\d)
(中国邮政编码为6位数字)◾ Email地址:
^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
◾ 帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):
◾ 密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线):
◾ 强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在 8-10 之间):
🔶 校验数字
^[0-9]*$
^\d{n}$
^\d{n,}$
^\d{m,n}$
^(0|[1-9][0-9]*)$
^(\-|\+)?\d+(\.\d+)?$
^[0-9]+(\.[0-9]{2})?$
^[0-9]+(\.[0-9]{1,3})?$
^[1-9]\d*$ 或 ^([1-9][0-9]*){1,3}$ 或 ^\+?[1-9][0-9]*$
^\-[1-9][]0-9"*$ 或 ^-[1-9]\d*$
🔶 校验字符
^[\u4e00-\u9fa5]{0,}$
^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$
^.{3,20}$
^[A-Za-z]+$
^[A-Z]+$
^[a-z]+$
^[A-Za-z0-9]+$
^\w+$ 或 ^\w{3,20}$
^[\u4E00-\u9FA5A-Za-z0-9_]+$
^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$
^%&',;=?$\"
等字符:[^%&',;=?$\x22]+
[^~\x22]+
参考
查看原文
查看全部文章
博文系列目录
交流
各系列文章汇总:https://github.com/yuanyuanbyte/Blog
我是圆圆,一名深耕于前端开发的攻城狮。