上一篇文章中我们讲了正则表达式的基本用法,接下来博主想聊聊其中的细节,今天就从正则修饰符开始吧。

正则修饰符又称为正则标记(flags),它会对正则的匹配规则做限定,进而影响匹配的最终结果。在上次的文章中我们也提到过,正则修饰符一共有以下几种,可以单独使用,也可以组合使用:

/\w+/g; // global search
/\w+/i; // ignore case
/\w+/m; // multi-line
/\w+/u; // unicode
/\w+/y; // sticky /\w+/gi;
new RegExp('\\w+', 'gi');

其中的i好理解,正如上面的注释一样,ignore case或case insensitive,忽略大小写。

下面是一个简单的例子,正则表达式加上了i修饰符之后也可以匹配到大写字母:

'Hello World'.match(/hello/i);  // ["Hello"]

/hello/i.exec('Hello World');   // ["Hello"]

再来看看全局匹配修饰符g,下面是一个全局匹配的例子:

var source = 'hello world hello JS';

source.match(/hello/);      // ["hello"]

source.match(/hello/g);     // ["hello", "hello"]

从上面代码中可以看出,普通正则的匹配结果只有一个,如果想要找出全部的匹配结果,后面则需要加一个g修饰符,使其成为全局匹配模式。

全局修饰符g通常也会和多行匹配修饰符m结合使用,我们将上面例子稍加改动,添加一个换行符,正则也稍加修改:

var source = 'hello world\nhello JS';

source.match(/^hello.+/g);    // ["hello world"]

大家会看到,我们是要在多行文本中匹配以"hello"开头的字符串,但结果只出现了第一个匹配项,后面的"hello JS"并未匹配到,这时我们需要加入多行匹配修饰符m:

var source = 'hello world\nhello JS';

source.match(/^hello.+/gm);   // ["hello world", "hello JS"]

现在,所有的结果都匹配到了。

但需要注意的是,单独使用修饰符m是不起作用的,它必须和g相结合,就像下面例子一样,虽然有m修饰符,但仍旧只匹配到了第一行文字:

var source = 'hello world\nhello JS';

source.match(/^hello.+/m);    // ["hello world"]

另外,还有一个很重要的条件,那就是,只有正则中包含起始标记"^"或结束标记"$"时,修饰符m才会发挥它的作用,否则g不需要m,且看下面例子:

// 只有匹配开始标记^或结束标记$时,g才需要m

var source = 'hello world\nhey world';

// 正则中没有^或$ 只需g即可匹配多行
source.match(/he.+/g); // ["hello world", "hey world"] // 正则中含有^或$ g只能匹配第一个结果
source.match(/^he.+/g); // ["hello world"]
source.match(/.+world$/g); // ["hey world"] // 含有^或$的情况下 需要添加m 才可以匹配多行
source.match(/^he.+/gm); // ["hello world", "hey world"]
source.match(/.+world$/gm); // ["hello world", "hey world"]

以上介绍的都是正则修饰符在String#match()方法中的表现,我们也知道,RegExp#exec()是与之对应的一个方法,同样可以匹配字符串,返回结果数组,那么这个exec()方法对于含有全局修饰符的正则又会有什么样的表现呢?实际操作发现,RegExp#exec()方法与上面String#match()的规则大致相同,但不同的是,RegExp#exec()方法每次只会匹配一个结果,所以需多次环执行才能获取全部。我们来看下面示例:

var regex = /^hello.+/gm;
var source = 'hello world\nhello JS'; regex.exec(source); // ["hello world"]
regex.exec(source); // ["hello JS"]

可以看到每一次执行正则实例的exec()方法都会返回一个结果数组,由于正则中含有起始标记^和gm组合,我们需要执行两次才能获取到全部的结果,这是与String#match()方法不同的地方。一般来说,我们可以使用循环结构调用RegExp#exec()方法来获取所有的结果:

var result = null;
while (result = regex.exec(source)) {
console.log(result);
}
// output:
// ["hello world"]
// ["hello JS"]

对于RegExp#test()方法,一般是用来检测字符串是否匹配某种模式,如果要在多行中检测任意一行是否匹配时,同样需要gm组合,下面代码先简单检测匹配情况,然后在多行中进行匹配:

var source = 'hello world\nhey JS';

/^hello.+/.test(source);      // true

/^hey.+/.test(source);        // false
/^hey.+/g.test(source); // false /^hey.+/gm.test(source); // true

从结果来看,不加gm修饰符的正则,只能检测一行数据的匹配情况,加入gm后可以对多行进行检测,只要任意一行符合条件,即返回true。

最后再来说说String#replace()方法,同样地,如果正则中出现了^或$,那就需要加上gm组合,下面代码演示了多行替换的操作:

var source = 'hello world\nhello JS';

// 正则中没有^或$,全局g轻松搞定
source.replace(/hello/g, 'hey'); // "hey world\nhey JS" // 正则中含有^或$,全局g也无能为力,仅能替换第一行
source.replace(/^hello/g, 'hey'); // "hey world\nhello JS" // 需要使用gm组合
source.replace(/^hello/gm, 'hey'); // "hey world\nhey JS"

上面是全局匹配g和多行匹配m,下面介绍一下u修饰符。

u修饰符是ES6新增特性,可以启用Unicode模式对字符串进行正则匹配,能正确处理四个字节的UTF-16字符集。为什么需要这个修饰符呢,我们先来看一个例子:

/^.{3}$/.test('你好啊');    // true
/^.{3}$/.test('

JavaScript: 详解正则表达式之二的更多相关文章

  1. JavaScript系列文章:详解正则表达式之二

    在上一篇文章中我们讲了正则表达式的基本用法,接下来博主想聊聊其中的细节,今天就从正则修饰符开始吧. 正则修饰符又称为正则标记(flags),它会对正则的匹配规则做限定,进而影响匹配的最终结果.在上次的 ...

  2. JavaScript: 详解正则表达式之三

    在上两篇文章中博主介绍了JavaScript中的正则常用方法和正则修饰符,今天准备聊一聊元字符和高级匹配的相关内容. 首先说说元字符,想必大家也都比较熟悉了,JS中的元字符有以下几种: / \ | . ...

  3. JavaScript: 详解正则表达式之一

    正则表达式是一个精巧的利器,经常用来在字符串中查找和替换,JavaScript语言参照Perl,也提供了正则表达式相关模块,开发当中非常实用,在一些类库或是框架中,比如jQuery,就存在大量的正则表 ...

  4. JavaScript学习笔记-实例详解-类(二)

    实例详解-类(二)   //===给Object.prototype添加只读\不可枚举\不可配置的属性objectId(function(){ Object.defineProperty(Object ...

  5. Android开发:文本控件详解——TextView(二)文字跑马灯效果实现

    一.需要使用的属性: 1.android:ellipsize 作用:若文字过长,控制该控件如何显示. 对于同样的文字“Android开发:文本控件详解——TextView(二)文字跑马灯效果实现”,不 ...

  6. Day03 javascript详解

    day03 js 详解 JavaScript的基础 JavaScript的变量 JavaScript的数据类型 JavaScript的语句 JavaScript的数组 JavaScript的函数 Ja ...

  7. dom对象详解--document对象(二)

       dom对象详解--style对象 style对象 style对象和document对象下的集合对象styleSheets有关系,styleSheets是文档中所有style对象的集合,这里讲解的 ...

  8. 【Java入门提高篇】Day30 Java容器类详解(十二)TreeMap详解

    今天来看看Map家族的另一名大将——TreeMap.前面已经介绍过Map家族的两名大将,分别是HashMap,LinkedHashMap.HashMap可以高效查找和存储元素,LinkedHashMa ...

  9. CocoaPods详解之(二)----进阶篇

    CocoaPods详解之----进阶篇 作者:wangzz 原文地址:http://blog.csdn.net/wzzvictory/article/details/19178709 转载请注明出处 ...

随机推荐

  1. django中安全sql注入等

    模拟sql注入 使用原生sql语句编写login登录逻辑 class LoginUnsafeView(View): def get(self, request): return render(requ ...

  2. matlab学习笔记12_2创建结构体数组,访问标量结构体,访问非标量结构体数组的属性,访问嵌套结构体中的数据,访问非标量结构体数组中多个元素的字段

    一起来学matlab-matlab学习笔记12 12_2 结构体 创建结构体数组,访问标量结构体,访问非标量结构体数组的属性,访问嵌套结构体中的数据,访问非标量结构体数组中多个元素的字段 觉得有用的话 ...

  3. Pandas的DataFrame

    1. 手工创建DataFrame a = [[1, 2, 2],[3,None,6],[3, 7, None],[5,None,7]] data = DataFrame(a) 2. Excel数据数据 ...

  4. 人脸识别(基于ArcFace)

    我们先来看看效果 上面是根据图片检测出其中的人脸.每个人脸的年龄还有性别,非常强大 第一步: 登录https://ai.arcsoft.com.cn/,注册开发者账号,身份认证,注册应用,得到APPI ...

  5. POI 读取Excel文件 并解析JSON数据

    package skuPrice; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundEx ...

  6. pytorch占用过多CPU问题

    Linux下,使用pytorch有时候会出现占用过多CPU资源的问题(占用过多线程),解决方法如下: 法一.torch.set_num_threads(int thread) (亲测比较有效) 法二. ...

  7. 贴子详情接口偶发时延超过2s的问题

    1. 发现问题     1. 查询慢access日志,发现偶尔有接口时延超过2s,发送概率1%左右 2. 排查     1. 写单元测试,多次测试后,不能重现问题     2. 接口代码里加日志,每隔 ...

  8. npm package

    lodash JavaScript 实用工具库,提供一致性,模块化,性能和配件等功能 用npm-run自动化任务 Express 4.x API 中文手册 Handlebars.js 模板引擎 使用n ...

  9. C#.NET LoadXml 时 “根级别上的数据无效。 行 1,位置 1”

    去除XML HEADER: <?xml version="1.0" encoding="utf-8"?> if (rspBusiXml.Contai ...

  10. 基础自动化部署搭建过程【Jenkins】

    测试环境搭建 为了快速搭建一套PHP测试环境我决定用laradock了,虽然文件很多,但是里面封装的东西也是比较全的,后期开发不知道会用到什么技术,就决定先用这个,随时可以启动用得到的服务.larad ...