理清JavaScript正则表达式--上篇
在JavaScript中,正则表达式由RegExp对象表示。RegExp对象呢,又可以通过直接量和构造函数RegExp两种方式创建,分别如下:
//直接量
var re = /pattern/[g | i | m];
//构造函数
var re = new RegExp(["pattern", ["g" | "i" | "m"]]);
其中,末尾的可选字符(g、i和m)分别表示:
g: 模式执行一个全局匹配。简而言之,就是找到所有匹配,而不是在找到第一个之后就停止。
i: 模式执行不区分大小写的匹配。
m: 多行模式,^和$锚除了匹配字符串的开头和结尾外,还匹配每行的开头和结尾。例如,模式/Java$/m匹配"Java"和"Java\nScript"。
| 基础篇 |
--特殊字符--
在正则表达式中,所有的字母字符和数字都可以按照直接量与自身匹配,如/JavaScript/匹配的就是字符串"JavaScript",但是有些特殊字符呢?如换行符。所以在JavaScript中规定以反斜杠(\)开头的转义序列支持这些特殊字符。常用的特殊字符如下:
|
转义字符 |
匹配 |
|
\n |
换行符 |
|
\r |
回车 |
|
\f |
换页符 |
|
\t |
制表符 |
|
\v |
垂直制表符 |
--字符类--
在正则表达式中,倘若将单独的字符放入方括号([ ])中,就可以组合成字符类。应用到匹配字符串中,我们可以将其看成一个漏斗,当字符串中的每个字符通过它时,都查找是否在这个类里面,如若在,就匹配成功,否则out。如下:
/*
match为字符串的方法,它的唯一参数就是一个正则表达式,
如果该正则表达式设置了标志g,该方法返回的数组包含的就是出现在字符串中的所有匹配。
详细的用法将在下面“正则表达式在String中的应用”细讲
*/
"abc".match(/[abc]/g);
匹配结果为:

如果我们的意愿是,想匹配除字符a、b、c之外的字符呢?我们可以定义一个否定类,只需将^符号放入[ ]中作为开头就OK啦。如下:
"abc".match(/[^abc]/g);
由于某些字符类经常用到,固JavaScript的正则表达式就用反斜杠(\)与一些特殊字符组合起来表示这些常用类,而不必再需要我们自行添加,如\d。
常用正则字符类如下:
|
字符类 |
匹配 |
例子 |
|
[ …] |
位于方括号之中的任意字符 |
/M[onke]y/ 匹配 "Moy" |
|
[ ^…] |
除包含在方括号之中的任意字符 |
/M[^onke]y/ 匹配 "May" |
|
. |
除换行符之外的任意字符 |
/../ 匹配 "Mo" |
|
\w |
字母、数字或下划线 |
/1\w/ 匹配 "1A" |
|
\W |
除字母、数字和下划线之外的字符 |
/1\W/ 匹配 "1%" |
|
\s |
单个空白字符 |
/M\sK/ 匹配 "M K" |
|
\S |
单个非空白字符 |
/M\SK/ 匹配 "M_K" |
|
\d |
0到9的数字 |
/\d/ 匹配 "1" |
|
\D |
非数字 |
/\D/ 匹配 "M" |
--重复匹配--
当我们需要匹配三位数字时,我们可以这样:/\d\d\d/,但是当我们需要匹配10位或者更多时呢?考虑到这一点,正则表达式为我们提供了重复字符{ n, m },表示匹配前一项至少n次,但是不能超过m次。例如,刚才我们所说的匹配三位数字时,我们可以利用重复字符这样啦:/\d{3}/。
由于某些重复类型经常用到,so,正则规定一些特殊字符表示这些重复类型。
正则重复字符,详情见下:
|
字符 |
含义 |
例子 |
|
{n, m} |
匹配前一项至少n次,但不能超过m次 |
/\d{2,3}/ 匹配"12" |
|
{n, } |
匹配前一项至少n次,或者更多 |
/\d{2, }/ 匹配"123" |
|
{n} |
匹配前一项恰好n次 |
/\d{2}/ 匹配"12" |
|
? |
匹配前一项0次或者1次,等价于{0,1} |
/\d?/ 匹配"2" |
|
+ |
匹配前一项1次或者多次,等价于{1, } |
/\d+/ 匹配"12" |
|
* |
匹配前一项0次或者多次,等价于{0, } |
/\d*/ 匹配"12" |
另,以上重复字符重复规则为:尽可能多的匹配,即俗称的“贪婪匹配”,如:"aaaa".match(/a+/);匹配的就是整个字符串"aaaa",而不是匹配到第一个字符a时,就放弃匹配。
那么,有所谓的"贪婪匹配",就有"非贪婪匹配",它的规则嘛,肯定与"贪婪匹配"相反咯,即:尽可能少的匹配。
那么,怎么才能触发非贪婪模式呢?
只需要在重复字符后加入?,就ok啦,如({1, 4}?、+?等),如"aaaa".match(/a+?/);就只会匹配首个字符a咯。
注意,是尽可能少的匹配,而不是少的匹配哦。
神马意思?如下:
"aaab".match(/a*b/);
"aaab".match(/a*?b/);
!匹配结果都是"aaab"!
有没有点诧异,为什么"aaab".match(/a*?b/);的匹配结果会是"aaab",而不是"ab"呢?
那是因为正则匹配都是从左往右的,就"aaab".match(/a*?b/);而言,当遇到首字符a时,它会继续往下匹配,直到能符合匹配模式/a*?b/为止,这就是为什么说是尽可能少的匹配,前提是满足匹配规则。
如"abbb".match(/ab*?/)的匹配结果就是"a"啦。
--字符 |、( )、(?: …)--
1.1、字符" | " 用于分隔,表示或。
什么意思?
举个栗子,如/ab | cd | ef/就可以匹配字符串"ab"或者"cd"或者"ef"。
是不是和字符类[ ]很像啊?
是的,如/a | b | c/和/[abc]/匹配效果是一样的哦。
But,字符类[ ]仅针对单个字符而言,而分隔字符" | "涉及更广,可以针对多个字符而言,如上述所说的/ab | cd | ef/,字符类就不行咯。
你可能会说,如果我想对利用" | "组装的类进行多次匹配呢?
加个括号就是啦。如:
/(ab | cd |ef)+/
好滴,说到括号,我们再来看看它的作用。非常强大哦。
1.2、括号"( )"
括号的作用如下:
1、我们可以将一个单独的项目组合成一个子表达式,以便我们可以用|、*等来处理它。如,上诉所示的/(ab | cd | ef)+/。
2、利用括号括起来的部分,我们可以在正则表达式的后面引用前面用括号括起来的子表达式的匹配结果,注意是结果,而不是括起来的正则表达式。
针对第二点,有什么用呢?如我们有个需求,我想匹配在单引号或者双引号中的数字(’12345’)时,我们就可轻而易举利用这第二点,写好正则表达式,如下:
/(['"])\d*\1/
测试结果如下:

好了,就第二点作用而言,结合上述demo,我们再来看看它的具体引用法则吧:
----以反斜杠\加数字的方式,引用前面带括号的子表达式,而这个数字呢指的就是第几个子表达式,计算规则为从左往右,计算遇到的左括号" ( ",到想引用的地方位置为止,无论在括号中还嵌套不嵌套括号。
测试Demo如下:

咦,倘若我只想让括号的作用为分组,而不想在后面计入引用呢?毕竟括号多了,不好计算呢。
那么,我们就来看看字符(?: …)咯。
1.3、(?: …)
(?: …)的作用就是,规定括号只用于分组,而不计入后面的引用,不好理解,看个demo就明白啦。如下:
/(Java(?:Script))(nice)/
如果我想在末尾引用子表达式nice,那么是\2,而不是\3咯,因为用(?: …)来分组滴,只管分组,而不引用,切记切记。
对(?: …)的测试demo如下:

--匹配位置--
在前面我们提到,创建正则对象时,可选字符m表示:多行模式,^和$锚除了匹配字符串的开头和结尾外,还匹配每行的开头和结尾。
那么这个^和$就是正则为我们提供的匹配位置,即所谓的锚。
例如:
将/JavaScript/变为/^JavaScript/,就只匹配字符串中开头为JavaScript的啦,如匹配"JavaScriptxxx"中的JavaScript,而不匹配"xxxJavaScript"中的JavaScript。
正则表达式中的锚字符详情见下:
|
字符 |
含义 |
|
^ |
匹配字符串的开头 |
|
$ |
匹配字符串的结尾 |
|
\b |
匹配一个词语的边界,指[a-zA-Z_0-9]之外的字符 |
|
\B |
匹配非词语边界位置 |
|
(? = p) |
正前向声明,exp1(?=exp2),匹配后面是exp2的exp1 |
|
(? ! p) |
反前向声明,exp1(?!exp2),匹配后面不是exp2的exp1 |
^和$好理解,但是\b、(?=)、(?!)可能比较陌生,结合上表,我们再来看看下面的demo就好啦。
对于\b的Demo如下:

对于(? = p)的Demo如下:

对于(? ! p)的Demo如下:

哎,本想一气呵成,没想到写完基础篇发现已经这么晚了。。。有时间再梳理下正则表达式在JavaScript中的应用吧。
具体应用,见"理清JavaScript正则表达式--下篇"
晚安,everyone~
理清JavaScript正则表达式--上篇的更多相关文章
- 理清JavaScript正则表达式--下篇
紧接:"理清JavaScript正则表达式--上篇". 正则在String类中的应用 类String支持四种利用正则表达式的方法.分别是search.replace.match和s ...
- 理清JavaScript正则表达式
理清JavaScript正则表达式--下篇 紧接:"理清JavaScript正则表达式--上篇". 正则在String类中的应用 类String支持四种利用正则表达式的方法.分别是 ...
- JavaScript正则表达式,你真的知道?
一.前言 粗浅的编写正则表达式,是造成性能瓶颈的主要原因.如下: var reg1 = /(A+A+)+B/; var reg2 = /AA+B/; 上述两个正则表达式,匹配效果是一样的,但是,效率就 ...
- JavaScript正则表达式下——相关方法
上篇博客JavaScript 正则表达式上——基本语法介绍了JavaScript正则表达式的语法,有了这些基本知识,可以看看正则表达式在JavaScript的应用了,在一切开始之前,看看RegExp实 ...
- JavaScript正则表达式学习笔记(二) - 打怪升级
本文接上篇,基础部分相对薄弱的同学请移步<JavaScript正则表达式学习笔记(一) - 理论基础>.上文介绍了8种JavaScript正则表达式的属性,本文还会追加介绍几种JavaSc ...
- 【JS】javascript 正则表达式 大全 总结
javascript 正则表达式 大全 总结 参考整理了一些javascript正则表达式 目的一:自我复习归纳总结 目的二:共享方便大家搜索 微信:wixf150 验证数字:^[0-9]*$ 验证n ...
- JavaScript正则表达式详解(一)正则表达式入门
JavaScript正则表达式是很多JavaScript开发人员比较头疼的事情,也很多人不愿意学习,只是必要的时候上网查一下就可以啦~本文中详细的把JavaScript正则表达式的用法进行了列表,希望 ...
- JavaScript正则表达式详解(二)JavaScript中正则表达式函数详解
二.JavaScript中正则表达式函数详解(exec, test, match, replace, search, split) 1.使用正则表达式的方法去匹配查找字符串 1.1. exec方法详解 ...
- Python自动化 【第十八篇】:JavaScript 正则表达式及Django初识
本节内容 JavaScript 正则表达式 Django初识 正则表达式 1.定义正则表达式 /.../ 用于定义正则表达式 /.../g 表示全局匹配 /.../i 表示不区分大小写 /.../m ...
随机推荐
- android自定义控件一站式入门
自定义控件 Android系统提供了一系列UI相关的类来帮助我们构造app的界面,以及完成交互的处理. 一般的,所有可以在窗口中被展示的UI对象类型,最终都是继承自View的类,这包括展示最终内容的非 ...
- SQLSERVER走起微信公众帐号已经开通搜狗微信搜索
SQLSERVER走起微信公众帐号已经开通搜狗微信搜索 请打开下面链接 http://weixin.sogou.com/gzh?openid=oIWsFt-hiIb_oYqQHaBMoNwRB2wM ...
- 使用 .NET WinForm 开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序
直接切入正题,这是我09年到11年左右业余时间编写的项目,最初的想法很简单,做一个能拖拖拽拽就直接生成应用程序的工具,不用写代码,把能想到的业务操作全部封装起来,通过配置的方式把这些业务操作组织起来运 ...
- 算法与数据结构(七) AOV网的拓扑排序
今天博客的内容依然与图有关,今天博客的主题是关于拓扑排序的.拓扑排序是基于AOV网的,关于AOV网的概念,我想引用下方这句话来介绍: AOV网:在现代化管理中,人们常用有向图来描述和分析一项工程的计划 ...
- 计算机程序的思维逻辑 (60) - 随机读写文件及其应用 - 实现一个简单的KV数据库
57节介绍了字节流, 58节介绍了字符流,它们都是以流的方式读写文件,流的方式有几个限制: 要么读,要么写,不能同时读和写 不能随机读写,只能从头读到尾,且不能重复读,虽然通过缓冲可以实现部分重读,但 ...
- ADO.NET编程之美----数据访问方式(面向连接与面向无连接)
最近,在学习ADO.NET时,其中提到了数据访问方式:面向连接与面向无连接.于是,百度了一下,发现并没有很好的资料,然而,在学校图书馆中发现一本好书(<ASP.NET MVC5 网站开发之美&g ...
- centos7 安装时候检测不到空余硬盘的解决办法
我是用U盘装的centos,在进行硬盘规划时,看到硬盘的可用空间太少 这是因为我的硬盘以前装的是windows系统,硬盘几乎都已经被windows 操作系统给使用了,剩余空间也只会是windows用剩 ...
- TCP/IP之TCP_NODELAY与TCP_CORK
TCP/IP之Nagle算法与40ms延迟提到了Nagle 算法.这样虽然提高了网络吞吐量,但是实时性却降低了,在一些交互性很强的应用程序来说是不允许的,使用TCP_NODELAY选项可以禁止Nagl ...
- Linux测试环境搭建的学习建议
随着Linux应用的扩展许多朋友开始接触Linux,根据学习Windwos的经验往往有一些茫然的感觉:不知从何处开始学起.这里介绍学习Linux测试环境搭建的一些建议. 一.Linux测试环境搭建从基 ...
- click事件的累加绑定,绑定一次点击事件,执行多次
最近做项目为一个添加按钮绑定点击事件,很简单的一个事情,于是我按照通常做法找到元素,使用jquery的on()方法为元素绑定了点击事件,点击同时发送请求.完成后看效果,第一次点击没有问题.再一次点击后 ...