1. RegExp 对象

JS 中像其他语言一样,有正则表达式的支持,即RegExp对象。

该对象主要提供了两个对象方法,分别是:

  1. exec()
  2. test()

用法示例如下:

let str = "cat bat";
let exp = /.at/g;
exp.exec(str); // ['cat', index: 0, input: 'cat bat', groups: undefined]
exp.exec(str); // ['bat', index: 4, input: 'cat bat', groups: undefined]
exp.exec(str); // null
let str = "cat bat";
let exp = /.at/g;
exp.test(str); // true

更多参看这里 link

2. 字符串模式匹配方法

但是在处理字符串时,以上方法并不常用,取而代之,String 类型专门为在字符串中实现模式匹配设计了几个方法。

  1. match();
  2. search();
  3. replace();

2.1 match()search()

其中, match()search() 方法的使用较为类似。 二者的使用示例如下:

let str = "cat, bat, sat, hat";
let pt = /.at/g;
let result = str.match(pt);
console.log(result);
/*
[
"cat",
"bat",
"sat",
"hat"
]
*/
let str = "cat, bat, sat, hat";
let pt = /.at/g;
let result = str.search(pt);
console.log(result); // 0

这两个方法都是接受一个参数, 是一个 正则表达式字符串,或者RegExp 对象。

所不同的是, match() 返回被匹配的项, 如果是/g 匹配模式,则返回一组包含所有匹配项的数组,否则,返回第一个匹配的到的子串, 其返回解雇结果和exec() 的执行结果相同。 而search() 的返回结果则是首个匹配项的索引值,如果没有匹配项则返回-1

2.2 replace()

重点的需要熟悉replace() 方法, 这是最常用的方法

为了简化子字符串替换操作,ECMAScript 提供了 replace() 方法。 这个方法接收两个参数,第一个参数可以是一个RegExp对象,或者一个字符串(这个字符串不会转换为正则表达式),第二个参数可以是一个字符串或者一个函数。

也就是,repalce() 方法可以单纯的用于替换字符串中的子串,也可以用以替换匹配模式匹配的目标子串。

  1. 替换子字符串,示例:

    let str = "cat, bat, sat, hat";
    let result = str.replace("at","hello");// chello, bat, sat, hat

    ️ 注意: 如果第一个参数是字符串,那么只会替换第一个子字符串。要是想替换所有的子字符串,第一个参数必须为正则表达式并且开启了全局匹配模式。

  2. 替换正则匹配项,示例:

    let str = "cat, bat, sat, hat";
    let pt = /at/g;
    let result = str.replace(pt,"hello");
    console.log(result);// chello, bhello, shello, hhello

2.2.1 第二个参数为字符串的应用情况

第二个参数是字符串的情况下,有几个特殊的字符序列,可以用来插入正则表达式操作的值。

字符序列 替换文本
$$ $
$& 匹配整个模式的子字符串。等同RegExp.lastMatch
$' 匹配的子字符串之前的字符串。 —— RegExp.rightContext
$` 匹配的子字符串之后的字符串。 —— RegExp。leftContext
$n 匹配第 n 个捕获组的子字符串, n ( 0~9 ), 若没有捕获组,值为空串。
$nn 匹配第 nn 个捕获组, nn (01~99), 若没有捕获组,值为空串。

以下示例说明:

let str = "I love the moment you smile";
let exp = /I (love (the moment(you)) smile/

该实例中,将会有三个捕获组:

$$

str.replace(exp,"$$"); // 将匹配到的子串替换为 `$` 符号
// '$'

️ 注意: 尽管是存在捕获组,但是因为整个模式就能匹配完整的源字符串, 还是直接全部被替换为了 $ 符号。

$&

str.replace(exp,"$&"); // 'I love the moment you smile'

$'$`

str.replace(exp,"$'"); // ''
str.replace(exp,"$`"); // ''
// "I love the moment you smile "为首个完整匹配,其左侧,右侧都是空字符

$n$nn

str.replace(exp,"$1"); //'love the moment you'
str.replace(exp,"$2"); //'the moment'
str.replace(exp,"$3"); //'you'

注意:

  1. 以上执行的含义是, 将第二个参数中的字符串,替换掉源字符串中被第一个参数(pattern)所匹配命中的子字符串。

  2. 以上的示例中,$', $` 的输出都是空串,以及$$ 直接返回$的原因是, $& 作为整个pattern 命中结果,已经和源字符串相同了,即整个完整的字符串被命中。 如果做以下修改,结果将不同:

    let str = 'I love the moment you smile';let exp = /love (the moment (you))/;str.replace(exp,"$$")// 'I $ smile'str.replace(exp,"$'")// 'I  smile smile'str.replace(exp,"$`")// 'I I  smile'

所以, 一点小结: 当字符串方法replace() 的第二个参数为字符串时, replace() 方法的替换目标是 $&

以上述示例来描述,就是 字符串 "I love the moment you smile" 的原始值包装对象提供的replace() 方法, 在通过正则表达式/love (the moment (you))/ 来进行内容替换时, 将会以整个pattern(表达式)匹配到的子串为目标,即 “love the moment you” 为替换目标,也就是$& 。 并无关于pattern 中是否有捕获组。

2.2.2 第二个参数为函数的应用情况

根据是否有捕获组,表现不同

replace() 方法第二个参数还支持函数, 目的是用于更加灵活的替换规则,拓展捕获组的使用需求等。

该函数根据第一个参数中(pattern) 是否具有捕获组,函数的传递参数也不同:

  1. 没有捕获组时 : 函数收到3个参数 :①. 与整个模式匹配的字符串 ②. 匹配项在字符串中的开始位置 ③. 整个字符串
  2. 有捕获组时 : 每个匹配捕获组的字符串都会作为参数传给这个函数,但是最后两个参数,依旧是 整个匹配模式开始的位置 和 原始字符串。 因此参数的个数时不确定的,为n + 2

以下是一些示例:

示例1 :没有捕获组:

示例2 : 只有一个捕获组:

示例3 : 有多个捕获组:

第二个参数为函数时的字符串替换示例:

示例1:

function htmlEscape(text) {   return text.replace(/[<>"&]/g, function(match, pos, originalText) {     switch(match) {        case "<":         return "&lt;";       case ">":         return "&gt;";       case "&":         return "&amp;";       case "\"":         return "&quot;";     }   }); }  console.log(htmlEscape("<p class=\"greeting\">Hello world!</p>")); // "&lt;p class=&quot;greeting&quot;&gt;Hello world!</p>"

​这个地方存在一个疑问:

不知道当Pattern 中含有捕获组的时候要怎么去处理, 例如:

let str = "i always love the way you lie";let exp = /always (love) the way (you) lie/;let res = str.replace(exp, function (...args) {  for (let i = 0; i < args.length; i++) {    if (args[i] === "love") {      return "hate";    } else if (args[i] === "you") {      return "she";    }  }});console.log(res); //i hate

期望是将源字符串中的 "love"->"hate", "you" -> "she" 。

[JS高程] 字符串模式匹配方法的更多相关文章

  1. JS常用字符串处理方法应用总结

    这篇文章主要总结了JS常用字符串的处理方法,需要的朋友可以参考下   1.indexOf()方法,从前往后查找字符串位置,大小写敏感,从0开始计数.同理,lastIndexOf() 方法从后往前,两个 ...

  2. js中字符串的方法

    js String对象中常用方法小结,需要的朋友可以参考下: 1.charCodeAt方法返回一个整数,代表指定位置字符的Unicode编码. strObj.charCodeAt(index) 说明: ...

  3. js常用字符串处理方法

    JS自带函数concat将两个或多个字符的文本组合起来,返回一个新的字符串.var a = "hello";var b = ",world";var c = a ...

  4. js截取字符串的方法

    1,slice(a, b) 第一个参数表示起始位置,第二个表示截取到但不包含 关于参数正负问题,只要记住一点:永远不能倒着截取!否则返回空字符串 2,substring(a, b) 第一个参数表示起始 ...

  5. js的字符串charAt()方法

    //字符中的字符从左向右进行索引,由0开始,字符串中的空格也算在内 var string = "charAt find word position"; document.write ...

  6. js 把字符串当做方法执行

    <SCRIPT LANGUAGE="JavaScript"> function test(str){ alert(str); } eval('test("aa ...

  7. RegExp实例方法和字符串的模式匹配方法的总结

    RegExp实例方法 ECMAScript通过RegExp类型来支持正则表达式,创建正则表达式有两种方式: //使用字面量形式定义正则表达式 var pattern1 = /[bc]at/i //使用 ...

  8. Js高程笔记->引用类型

    1 . Object 对象    2 . Array 对象 :       检测方法:ES5 : isArray       转换方法: toLocaleString , toString , val ...

  9. js中A包含B的写法与分割字符串的方法

    在java中A包含B的写法 if(A.contains(B)){ ... } 在js中没有contains方法,应该使用下面这种方法: var an = "传染性.潜伏性.破坏性" ...

随机推荐

  1. logstash输出到rabbitmq

    场景 将应用日志文件发送到rabbitmq. filebeat 不支持rabbitmq作为输出.因此,需要先将文件由filebeat发送到logstash ,再由logstash 输出到rabbitm ...

  2. 题解 「HDU6403」卡片游戏

    link Description 桌面上摊开着一些卡牌,这是她平时很爱玩的一个游戏.如今卡牌还在,她却不在我身边.不知不觉,我翻开了卡牌,回忆起了当时一起玩卡牌的那段时间. 每张卡牌的正面与反面都各有 ...

  3. 题解 [HNOI/AHOI2018]毒瘤

    题目传送门 题目大意 给出一个 \(n\) 个点 \(m\) 条边的无向图,问有多少个点集满足点集中任意两点均不存在边相连. \(n\le 10^5,m-n\le 10\),答案对 \(9982443 ...

  4. pycharm上的python虚拟环境移到离线机器上

    Pycharm的Terminal 中执行: 查看现有的包到requirements.txt中 pip freeze > requirements.txt 生成依赖包 D:\machangwei\ ...

  5. Linux——Docker安装

    1. 安装Docker i :环境准备:Linux要求内核3.0以上 ii:安装 #1.卸载旧版本 yum remove docker \ docker-client \ docker-client- ...

  6. 听说,99% 的 Go 程序员都被 defer 坑过

    原文链接: 听说,99% 的 Go 程序员都被 defer 坑过 先声明:我被坑过. 之前写 Go 专栏时,写过一篇文章:Go 专栏|错误处理:defer,panic 和 recover.有小伙伴留言 ...

  7. pandas 取 groupby 后每个分组的前 N 行

    原始数据如下: (图是从 excel 截的,最左1行不是数据,是 excel 自带的行号,为了方便说明截进来的) 除去首行是标题外,有效数据为 28行 x 4列 目前的需求是根据 partition ...

  8. 你对微信小程序的理解?优缺点?

    一.是什么 2017年,微信正式推出了小程序,允许外部开发者在微信内部运行自己的代码,开展业务 截至目前,小程序已经成为国内前端的一个重要业务,跟 Web 和手机 App 有着同等的重要性 小程序是一 ...

  9. 【UE4 设计模式】单例模式 Singleton Pattern

    概述 描述 保证一个类只有一个实例 提供一个访问该实例的全局节点,可以视为一个全局变量 仅在首次请求单例对象时对其进行初始化. 套路 将默认构造函数设为私有, 防止其他对象使用单例类的 new运算符. ...

  10. 第四次Scrum Metting

    日期:2021年4月29日 会议主要内容概述:交代近两日工作,进一步细化上次讨论细节,代码合并. 一.进度情况## 组员 负责 两日内已完成的工作 后两日计划完成的工作 工作中遇到的困难 徐宇龙 后端 ...