- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章JavaScript系列文章:详解正则表达式基本知识由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
正则表达式是一个精巧的利器,经常用来在字符串中查找和替换,JavaScript语言参照Perl,也提供了正则表达式相关模块,开发当中非常实用,在一些类库或是框架中,比如jQuery,就存在大量的正则表达式,所以说学好正则表达式,是提高开发技能的一项基本要求。那么今天博主就来详细总结一下正则表达式的相关知识,希望不熟悉的同学们,也能够掌握正则表达式的原理及应用.
在JS中,创建正则表达式有两种方式,一种是字面量方式,一种是构造器方式,如下所示:
1
2
3
4
5
|
var
regex = /\w+/;
// 或者
var
regex =
new
RegExp(
'\\w+'
);
|
大家也许注意到,使用字面量要比构造器简洁得多,\w表示一个word,匹配单个字母、数字或下划线,而使用RegExp构造器时,我们的正则变为了"\\w",这是因为要在字符串中表示一个反斜杠\,我们需要对其转义,也就是在前面再加一个转义字符\。相信大家都知道,要在字面量正则中表达一个匹配反斜杠\的正则,只需写成\\这样,但在字符串中表达这个正则,则是"\\\\"这个样子的,这是因为字符串中前两个表示一个反斜杠\,后两个也表示一个反斜杠\,最终在正则层面,结果还是\\.
对于上面两种创建形式,都可以加上一些后缀修饰符,这些修饰符可以单个使用,也可以组合起来使用:
。
。
从英文注释来看,相信大家都大概都略知一二了,需要注意的是u和y修饰符,它们是ES6新增的特性,u表示启用Unicode模式,对于匹配中文特别有用,而y是sticky,表示“粘连”,跟g很相似,都属于全局匹配,但它们也有不同之处,这个我们后面会介绍.
正则相关方法 。
有了正则表达式对象了,如何使用呢?JS中的正则和字符串在原型中均提供相应的方法,先来看看正则原型中的两个方法:
1
2
|
RegExp.prototype.test(str);
RegExp.prototype.exec(str);
|
上面的test()和exec()方法都需传入一个字符串,对这个字符串进行搜索和匹配,不同的是,test()方法会返回true或false,表示字符串和正则是否匹配,而exec()方法在匹配时返回一个匹配结果数组,如果不匹配,则只返回一个null值,下面来看看两者的差异:
1
2
3
4
5
6
7
8
9
|
// RegExp#test()
var
regex = /hello/;
var
result = regex.test(
'hello world'
);
// true
// RegExp#exec()
var
regex = /hello/;
var
result = regex.exec(
'hello world'
);
// ['hello']
|
对于exec()方法,如果正则中含有捕获组,匹配后则会出现在结果数组中:
1
2
3
4
|
// (llo)是一个捕获组
var
regex = /he(llo)/;
var
result = regex.exec(
'hello world'
);
// ['hello', 'llo']
|
开发当中,test()方法一般用于用户输入验证,比如邮箱验证,手机号验证等等,而exec()方法一般用于从特定内容中获取有价值的信息,比如从用户邮箱输入中获取其ID和邮箱类型,从手机号中获取此号码的归属地等等.
字符串相关方法 。
上面是正则原型中的两个方法,现在来看看字符串原型中都提供了哪些可用的方法:
1
2
3
4
|
String.prototype.search(regexp);
String.prototype.match(regexp);
String.prototype.split([separator[, limit]]);
String.prototype.replace(regexp|substr, newSubStr|
function
);
|
先来说说String#search()方法,它会根据正则参数对字符串进行匹配搜索,如果匹配成功,就返回第一次匹配处的索引,如果匹配失败,则返回-1.
1
2
3
4
5
|
// String#search()
'hello world'
.search(/hello/);
// 0
'hello world'
.search(/hi/);
// -1
|
String#match()方法跟RegExp#exec()方法相似,会返回结果数组,所不同的是,如果String#match()的正则参数中含有全局标记g,则结果中会只出现匹配的子串,而忽略捕获组,这一点与RegExp#exec()有些出入。且看下面代码:
1
2
3
4
5
6
7
8
9
10
11
|
// String#match()
'hello hello'
.match(/he(llo)/);
// ['hello', 'llo']
// String#match()遇到全局g修饰符时会舍弃捕获组
'hello hello'
.match(/he(llo)/g);
// ['hello', 'hello']
// RegExp#exec()仍旧包含捕获组
/he(llo)/g.exec(
'hello hello'
);
// ['hello', 'llo']
|
所以,如果需要总是将捕获组作为结果返回,应该使用RegExp#exec()方法,而不是String#match()方法.
接下来说说String#split()方法,这个方法用于将字符串分割,然后返回一个包含其子串的数组结果,其中separator和limit参数都是可选的,separator可指定为字符串或正则,limit指定返回结果个数的最大限制。如果separator省略,该方法的数组结果中仅包含自身源字符串;如果sparator指定一个空字符串,则源字符串将被以字符为单位进行分割;如果separator是非空字符串或正则表达式,则该方法会以此参数为单位对源字符串进行分割处理。下面代码演示了该方法的使用:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
// String#split()
'hello'
.split();
// ["hello"]
'hello'
.split(
''
);
// ["h", "e", "l", "l", "o"]
'hello'
.split(
''
, 3);
// ["h", "e", "l"]
// 指定一个非空字符串
var
source =
'hello world'
;
var
result = source.split(
' '
);
// ["hello", "world"]
// 或者使用正则表达式
var
result = source.split(/\s/);
// ["hello", "world"]
如果separtor是一个正则表达式,并且正则中包含捕获组,则捕获组也会出现在结果数组中:
// String#split() 正则捕获组
var
source =
'matchandsplit'
;
var
result = source.split(
'and'
);
// ["match", "split"]
var
result = source.split(/and/);
// ["match", "split"]
// 正则中含捕获组
var
result = source.split(/(and)/);
// ["match", "and", "split"]
|
最后来介绍一下String#replace()方法,它会同时执行查找和替换两个操作.
从上面的函数签名来看,该方法会接受两个参数:第一个参数可以是一个正则表达式,也可以是一个字符串,它们都表示将要匹配的子串;第二个参数可以指定一个字符串或是一个函数,如果指定一个字符串,表示这个字符串将会替换掉已匹配到的子串,如果指定一个函数,则函数的返回值会替换掉已匹配的子串.
String#replace()方法最终会返回一个新的已经过替换的字符串。下面分别演示了replace方法的使用:
1
2
3
4
5
6
7
8
9
10
11
|
// String#replace()
var
source =
'matchandsplitandreplace'
;
var
result = source.replace(
'and'
,
'-'
);
// "match-splitandreplace"
// 或者
var
result = source.replace(/and/,
function
() {
return
'-'
;
});
// "match-splitandreplace"
|
从上面的代码中可以看到,'and'被替换成了'-',但我们同时也注意到,只有第一个'and'被替换了,后面的并没有被处理。这里我们就需要了解,String#replace()方法只对第一次出现的匹配串进行替换,如果我们需要全局替换,需要将第一个参数指定为正则表达式,并追加全局g修饰符,就像下面这样:
1
2
3
4
5
6
7
8
9
|
// String#replace() 全局替换
var
source =
'matchandsplitandreplace'
;
var
result = source.replace(/and/g,
'-'
);
// "match-split-replace"
var
result = source.replace(/and/g,
function
() {
return
'-'
;
});
// "match-split-replace"
|
初学者看到上面的代码,可能会觉得疑惑,对于第二个参数,直接指定一个字符串也挺简单的嘛,我们为何要使用一个函数然后再返回一个值呢。我们看看下面的例子就知道了:
1
2
3
4
5
6
7
8
9
10
11
12
|
// String#replace() 替换函数的参数列表
var
source =
'matchandsplitandreplace'
;
var
result = source.replace(/(a(nd))/g,
function
(match, p1, p2, offset, string) {
console.group(
'match:'
);
console.log(match, p1, p2, offset, string);
console.groupEnd();
return
'-'
;
});
// "match-split-replace"
|
上面代码中,第一个参数是正则表达式,其中包含了两个捕获组(and)和(nd),第二个参数指定一个匿名函数,其函数列表中有一些参数:match, p1, p2, offset, string,分别对应匹配到的子串、第一个捕获组、第二个捕获组、匹配子串在源字符串中的索引、源字符串,我们可以称这个匿名函数为“replacer”或“替换函数”,在替换函数的参数列表中,match、offset和string在每一次匹配时总是存在的,而中间的p1、p2等捕获组,String#replace()方法会根据实际匹配情况去填充,当然,我们还可以根据arguments获取到这些参数值.
下面是代码运行后的控制台打印结果:
现在来看,指定一个函数要比指定一个字符串功能强的多,每次匹配都能获取到这些有用的信息,我们可以对其进行一些操作处理,最后再返回一个值,作为要替换的新子串。所以推荐在调用String#replace()方法时,使用上面这种方式.
上面是String类与正则相关的常用方法,需要注意的是,String#search()和String#match()方法签名中参数均为正则对象,如果我们传递了其他类型的参数,会被隐式转换为正则对象,具体的步骤是先调用参数值的toString()方法得到字符串类型的值,然后调用new RegExp(val)得到正则对象:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
// -> String#search(new RegExp(val.toString()))
'123 123'
.search(1);
// 0
'true false'
.search(
true
);
// 0
'123 123'
.search(
'\\s'
);
// 3
var
o = {
toString:
function
() {
return
'\\s'
;
}
};
'123 123'
.search(o);
// 3
// -> String#match(new RegExp(val.toString()))
'123 123'
.match(1);
// ["1"]
'true false'
.match(
true
);
// ["true"]
'123 123'
.match(
'\\s'
);
// [" "]
var
o = {
toString:
function
() {
return
'1(23)'
;
}
};
'123 123'
.match(o);
// "123", "23"]
|
而split()和replace()方法不会将字符串转为正则表达式对象,对于其他类型值,只会调用其toString()方法将参数值转为字符串,也不会进一步向正则转换,大家可以亲自测试一下.
以上就是正则的相关基本知识及常用方法,限于篇幅原因,更多关于正则表达式的内容,博主会安排在下一篇中介绍和讲解,敬请期待.
原文链接:http://www.cnblogs.com/liuhe688/p/6087795.html 。
最后此篇关于JavaScript系列文章:详解正则表达式基本知识的文章就讲到这里了,如果你想了解更多关于JavaScript系列文章:详解正则表达式基本知识的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正在尝试创建一个 Django 网站,每次在本地主机上运行/articles/api/article 页面时:我都会收到此回溯: Environment: Request Method: GET R
我正在尽最大努力理解开放图谱协议(protocol)中的一切含义阅读 FB page在上面和 OGP Page .这在 FB 和 OGP 的世界中究竟意味着什么: Note that the Open
我的 HTML/CSS 中存在页脚与文章内容重叠的问题。是的,我一直在网上搜索但似乎没有任何效果,我希望你知道它有什么问题。我在这里做了一个codepen: CodePen LINK
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
我可以将变量作为警报显示在函数中,但无法将变量传递给文章。我做错了什么? 我知道“a”保存了正确的信息,因为我已经通过警报显示了它。 我尝试使用以下方式传递变量:placeholderContent.
这个问题已经有答案了: Rails article helper - "a" or "an" (6 个回答) 已关闭 3 年前。 是否有类似 [#pluralize in ActiveSupport]
这个问题已经有答案了: Rails article helper - "a" or "an" (6 个回答) 已关闭 3 年前。 是否有类似 [#pluralize in ActiveSupport]
我有以下型号。 Book has Articles (Article has foreign key to Book) Article has Images (Article has upto #ma
我创建了一个页面,该页面显示了单个 类别下的所有帖子,即如果我单击类别音乐,我将获得与音乐类别相关的所有文章。 但我的目标是创建一个过滤选项,它可以过滤掉某些类别,并且只显示与您过滤的类别相关的所有帖
我使用这样的代码: $query = "SELECT introtext FROM #__content WHERE alias = '$alias'"; $db->setQuery($query);
我在主页上设置了一些特色文章。显示的所有文章似乎都剩下太多填充。我知道足以进入 css 并在 layout.css 上编辑 .itembody 的填充或边距,但似乎没有任何改变。我希望我的文章通过模块
ORM 中存储文章及其修订的最佳实践是什么?当我自己用SQL存储时,我曾经有以下结构: articles [id, parent_id, name, text] 通过parent_id,我可以轻松识
我的 HTML : Interest About Interest
我正在用jade构建一个nodejs、express、mongodb博客。 我的文件夹结构是:项目/ 模块/ 观点/ 索引.jade 应用程序.js 文章提供者内存.js 文章provider-mon
我的问题比较具体,至少对我来说是这样。具体是因为在做了很多搜索之后我找不到任何有用的东西。因此,正如标题所说,我正在寻找一种算法,它会发现输入中给出的两篇文章是否“匹配”,但不是通常的字符串匹配意义上
关闭。这个问题是off-topic .它目前不接受答案。 9年前关闭。 锁定。这个问题及其答案是locked因为这个问题是题外话,但具有历史意义。它目前不接受新的答案或互动。 我无法弄清楚动态编程的原
我有这个问题。我正在建立一个社交网站,我必须在两栏中创建帖子。父容器是一个部分,元素“post”是样式为 float: left 的文章。我如何让滑到那些较短的下方创建的空白空间的帖子? 最佳答案 c
这里有几个关于文件与数据库的问题,但我仍然不确定使用什么以及为什么在我的案例中应该使用它。 我的网站上有很多 HTML 文章(长度在几百到几千字之间)。在数据库 (MySQL) 中,我有一个没有搜索索
微信公众号文章 Semantic Kernel —— LangChain 的替代品? [1] ,它使用的示例代码是Python ,他却发了这么一个疑问: 支持的语言对比(因为 Sem
我想编写一个 polymer 元素来显示一些 WordPress 文章。 http://www.jsv-lippstadt.de/?json=get_category_posts&slug=app
我是一名优秀的程序员,十分优秀!