JS中的正则表达式

前言

接触与研究代码的时间不长,却早早就知道了正则表达式大体是什么以及它能实现的强大功能。但是我一直没有深入,因为这玩意看了头疼。最近没有什么工作安排,所以准备探讨一番。

JS regExp

基本语法

JS中有一个 regExp 对象,它表示正则表达式,可以对字符串执行强大的匹配功能。在 JS 中,正则表达式可以有两种表现语法:
字面量语法

/pattern/attributes

RegExp 对象的语法

new RegExp(pattern, attributes);


参数
1、 参数 pattern 是一个字符串,指定了正则表达式的模式或其他正则表达式。
2、 参数 attributes 是一个可选的字符串,包含属性 "g"、"i" 和 "m",分别用于指定全局匹配、区分大小写的匹配和多行匹配。

在创建正则表达式时,如果不按照规范创建对象,很容易会导致错误。如 pattern 不规范:

new RegExp(/me, "g");   //    不规范的表达式

又如 attributes 包含除"m","i","g"以外的字符

new RegExp(/me/, "o");  //    不合法的属性

对于RegExp 对象的语法,如果给定 pattern 是完整正则表达式且带有合法属性参数时,不可再设置属性,如

new RegExp(/me/g, "i"); //    Uncaught TypeError
new RegExp(/me/, "i");  //    Uncaught TypeError(即使 pattern 没有指定属性,但已有默认的属性值)
new RegExp(/me/gi); //    /me/gi

返回值

当你要使用 RegExp 对象的时候,你会发现 RegExp 对象的返回值就是该正则表达式的字面量形式,二者的作用是完全等同的,但不完全等同,这里说的只是“作用”。为什么不完全等同呢?当你要创建一个正则表达式对象时,无论你用的是直接字面量形式还是创建 RegExp 对象形式,你所得到的都只是 RegExp 对象的一个实例,而对象的每一个实例都是不等同的。例如:

var pattern1 = /me/g;
var pattern2 = /me/g;
alert(pattern1==pattern2);  // false,用 RegExp 对象创建亦然
alert(new RegExp("me","g")==new RegExp("me","g"));  // false
当正则表达式实例遇上全局匹配"g"

属性 "g" 是一个很有用的模式,它提供全局匹配可以让我们省很多事。但是它有一个特性:对于同一个全局匹配的正则表达式实例,在实行一次(局部)匹配后,它下次匹配的起点会停留在本次匹配的尾部。这是要怎么理解呢?上代码

var p1 = /me/g; // 全局匹配"me"字符串
alert(p1.test("ome"));  // true
alert(p1.test("ome"));  // false,这里为什么是false??
alert(p1.test("ome"));  // true,又变回true了?

这里的表现很有趣,仿佛一个正则表达式加上 "g" 参数就变得如中二女青年一样“反复无常”,时而 true 时而 false。这是因为 RegExp 对象有一个 lastIndex 属性,它会记录上次匹配成功的位置。对于同一个 RegExp 全局匹配实例来说,对于它的 lastIndex 可以解释如下:

var p1 = /me/g; // 全局匹配"me"字符串
alert(p1.test("ome"));  // true 这里匹配到 me 是位置3,lastIndex = 3,下次匹配就从位置3开始
alert(p1.test("ome"));  // false 但是位置3已经是字符串尾部,没能够再找到 me 了,所以返回 false
alert(p1.test("ome"));  // true 上次到了字符串的尾部,现在就从新开始,lastIndex = 0

上面的解析已经足够清楚,但是为了验证其正确性,不妨再看看:

var p1 = /me/g; // 全局匹配"me"字符串
alert(p1.test("ome"));  // true 这里匹配到 me 是位置3,下次匹配就从位置3开始
alert(p1.test("omeooome")); // true 从位置3开始寻找下一个 me ,尾部可以找到一个 me,所以返回 true

细心的人可能看到我在上面给“同一个”着重加粗了,原因我想已经很显然了。对于功能相同但不等同的 RegExp 对象实例,"g" 所引起的小坑就不存在了。如下代码:

var p1 = /me/g; // 全局匹配"me"字符串
alert(p1.test("ome"));  // true
p1 = /me/g;
alert(p1.test("ome"));  // true

这里可能需要解释下,当 p1 被重新赋值后,哪怕是一模一样的内容,它也是 RegExp 对象的一个新的实例。

RegExp 对象方法

exec() 方法

exec() 方法用于检索字符串中的正则表达式的匹配。其语法为:

RegExpObject.exec(string)

执行该方法会返回一个数组,其中存放匹配的结果。如果未找到匹配,则返回值为 null。

test() 方法

test() 方法用于检索字符串中的正则表达式的匹配。其语法为:

RegExpObject.test(string)

执行该方法会返回布尔值,如果找到匹配,则返回值为 true,否则为 false。

compile() 方法

compile() 方法用于检索字符串中的正则表达式的匹配。其语法为:

RegExpObject.compile(string)

在当前浏览器环境中,我还真不知道这个东西有什么鬼用。文档是说:compile() 方法用于在脚本执行过程中编译,改变和重新编译正则表达式。

支持正则表达式的 String 对象的方法

search()

search() 方法用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串。
语法:

stringObject.search(regexp)

执行该方法会返回 stringObject 中第一个与 regexp 相匹配的子串的起始位置。如果没有找到任何匹配的子串,则返回 -1。
注意:search() 方法不执行全局匹配,它将忽略标志 g。它同时忽略 regexp 的 lastIndex 属性,并且总是从字符串的开始进行检索,这意味着它总是返回 stringObject 的第一个匹配的位置。

match()

match() 方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。
语法:

stringObject.match(regexp)

执行该方法会返回存放匹配结果的数组。该数组的内容依赖于 regexp 是否具有全局标志 g。
注意
如果 regexp 没有标志 g,那么 match() 方法就只能在 stringObject 中执行一次匹配。如果没有找到任何匹配的文本, match() 将返回 null。否则,它将返回一个数组,其中存放了与它找到的匹配文本有关的信息。
如果 regexp 具有标志 g,则 match() 方法将执行全局检索,找到 stringObject 中的所有匹配子字符串。若没有找到任何匹配的子串,则返回 null。如果找到了一个或多个匹配子串,则返回一个数组。不过全局匹配返回的数组的内容与前者大不相同,它的数组元素中存放的是 stringObject 中所有的匹配子串,而且也没有 index 属性或 input 属性。

replace()

replace() 方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。
语法:

stringObject.replace(regexp/substr,replacement)

执行该方法会返回一个新的字符串,是用 replacement 替换了 regexp 的第一次匹配或所有匹配之后得到的。

split()

split() 方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。
语法:

stringObject.split(separator,howmany)

split() 方法用于把一个字符串分割成字符串数组。
注意
separator 是字符串或正则表达式,从该参数指定的地方分割 stringObject。

总结

说了那么多,总算是把 JS 正则表达式中最浅显的一层总结理解了一番,细细想想,这篇文章还没有考虑到“正则表达式基础知识”,“如何根据需求写正则表达式”,“子正则表达式”...................

苍天啊!!
大地啊!!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342

推荐阅读更多精彩内容