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. WEB 标准以及 W3C 的理解与认识

    01.  WEB标准 ①  web标准 简单来说可以分为结构.表现和行为. ②  结构:主要是有HTML标签组成(通俗点说,在页面body里面我们写入的标签都是为了页面的结构)   表现:即指css样 ...

  2. 洛谷2543AHOI2005]航线规划 (树剖+线段树+割边思路)

    这个题的思路还是比较巧妙的. 首先,我们发现操作只有删除和询问两种,而删除并不好维护连通性和割边之类的信息. 所以我们不妨像WC2006水管局长那样,将询问离线,然后把操作转化成加边和询问. 然后,我 ...

  3. Billu_b0x2内网渗透(多种提权方法)靶场-vulnhub

    个人博客阅读体验更佳 本次来试玩一下vulnhub上的Billu_b0x2,下载地址. 下载下来后是 .ova 格式,建议使用vitualbox进行搭建,vmware可能存在兼容性问题.靶场推荐使用N ...

  4. Win10 配置JDK1.8 (JDK 8)环境变量

    JDK的安装: 1. JDK安装过程中,一般X掉公共JRE,因为JDK包含了JRE:     环境变量的配置: 1. 打开环境变量,编辑系统变量,新建: 变量名:JAVA_HOME 变量值:D:\so ...

  5. c语言中“ld返回值1退回状态”

    在c语言运行中我们经常会看到error:ld return 1 exit status的运行错误,其翻译为"ld返回值1退回状态".在生成程序时.有多个工具参与到步骤的运行中以创建 ...

  6. 5个步骤,教你瞬间明白线程和线程安全.md

    记得刚来杭州面试的时候,有一家公司的技术总监问了我这样一个问题:你来说说有哪些线程安全的类?我心里一想,这我早都背好了,稀里哗啦说了一大堆. 他又接着问:那你再来说说什么是线程安全?--然后我就GG了 ...

  7. 【c++ Prime 学习笔记】第19章 特殊工具与技术

    某些程序对内存分配有特殊要求,不能直接使用标准内存管理机制 重载new和delete算符可控制内存分配的过程 19.1.1 重载new和delete 说法"重载new和delete" ...

  8. Coursera Deep Learning笔记 卷积神经网络基础

    参考1 参考2 1. 计算机视觉 使用传统神经网络处理机器视觉的一个主要问题是输入层维度很大.例如一张64x64x3的图片,神经网络输入层的维度为12288. 如果图片尺寸较大,例如一张1000x10 ...

  9. 技术博客——微信小程序UI的设计与美化

    技术博客--微信小程序UI的设计与美化 在alpha阶段的开发过后,我们的小程序也上线了.看到自己努力之后的成果大家都很开心,但对比已有的表情包小程序,我们的界面还有很大的提升空间,许多的界面都是各个 ...

  10. Noip模拟20 2021.7.19

    T1 玩具 题目读错意思直接报零... 拼接方式没读懂以为是个数学题,用卡特兰数,可是的确想多了 数据范围表达出你怎么暴力都行,选择$n^3,dp$ 相当于一片森林,每次多加一条边就合并成一棵树 在$ ...