[JS高程]|[JS高程] 字符串模式匹配方法
目录
- 1. RegExp 对象
- 2. 字符串模式匹配方法
- 2.1 match() , search()
- 2.2 replace()
- 2.2.1 第二个参数为字符串的应用情况
- 2.2.2 第二个参数为函数的应用情况
1. RegExp 对象 JS 中像其他语言一样,有正则表达式的支持,即RegExp对象。
该对象主要提供了两个对象方法,分别是:
exec()
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
类型专门为在字符串中实现模式匹配设计了几个方法。match()
;search()
;replace()
;
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()
方法可以单纯的用于替换字符串中的子串,也可以用以替换匹配模式匹配的目标子串。- 替换子字符串,示例:
let str = "cat, bat, sat, hat"; let result = str.replace("at","hello"); // chello, bat, sat, hat
?? 注意: 如果第一个参数是字符串,那么只会替换第一个子字符串。要是想替换所有的子字符串,第一个参数必须为正则表达式并且开启了全局匹配模式。
- 替换正则匹配项,示例:
let str = "cat, bat, sat, hat"; let pt = /at/g; let result = str.replace(pt,"hello"); console.log(result); // chello, bhello, shello, hhello
字符序列 | 替换文本 |
---|---|
$$ |
$ |
$& |
匹配整个模式的子字符串。等同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'
【[JS高程]|[JS高程] 字符串模式匹配方法】注意:
- 以上执行的含义是, 将第二个参数中的字符串,替换掉源字符串中被第一个参数(pattern)所匹配命中的子字符串。
- 以上的示例中,
$'
,$`
的输出都是空串,以及$$
直接返回$
的原因是,$&
作为整个pattern 命中结果,已经和源字符串相同了,即整个完整的字符串被命中。 如果做以下修改,结果将不同:
let str = 'I love the moment you smile'; let exp = /love (the moment (you))/; str.replace(exp,"$$")// 'I $ smile'str.replace(exp,"$'")// 'Ismile smile'str.replace(exp,"$`")// 'I Ismile'
replace()
的第二个参数为字符串时, replace()
方法的替换目标是 $&以上述示例来描述,就是 字符串 "I love the moment you smile" 的原始值包装对象提供的
replace()
方法, 在通过正则表达式/love (the moment (you))/
来进行内容替换时, 将会以整个pattern(表达式)匹配到的子串为目标,即 “love the moment you” 为替换目标,也就是$&
。 并无关于pattern 中是否有捕获组。2.2.2 第二个参数为函数的应用情况 根据是否有捕获组,表现不同
replace()
方法第二个参数还支持函数, 目的是用于更加灵活的替换规则,拓展捕获组的使用需求等。该函数根据第一个参数中(pattern) 是否具有捕获组,函数的传递参数也不同:
- 没有捕获组时 : 函数收到3个参数 :①. 与整个模式匹配的字符串 ②. 匹配项在字符串中的开始位置 ③. 整个字符串
- 有捕获组时 : 每个匹配捕获组的字符串都会作为参数传给这个函数,但是最后两个参数,依旧是 整个匹配模式开始的位置 和 原始字符串。 因此参数的个数时不确定的,为
n + 2
示例1 :没有捕获组:
文章图片
示例2 : 只有一个捕获组:
文章图片
示例3 : 有多个捕获组:
文章图片
第二个参数为函数时的字符串替换示例:
示例1:
function htmlEscape(text) {return text.replace(/[<>"&]/g, function(match, pos, originalText) {switch(match) {case "<":return "<
";
case ">":return ">
";
case "&":return "&
";
case "\"":return ""
";
}});
}console.log(htmlEscape("Hello world!
"));
// "<
p class="
greeting"
>
Hello world!
"
? ?这个地方存在一个疑问:
不知道当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" 。
推荐阅读
- 一起来学习C语言的字符串转换函数
- 字符串拼接成段落,换行符(\n)如何只执行n-1次
- --木木--|--木木-- 第二课作业#翼丰会(每日一淘6+1实战裂变被动引流# 6+1模式)
- C语言的版本比较
- 设计模式-代理模式-Proxy
- 【译】Rails|【译】Rails 5.0正式发布(Action Cable,API模式等)
- java静态代理模式
- VueX(Vuex|VueX(Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式)
- Kotlin基础(10)-代理模式在kotlin中的使用
- 长谈的确是这个时代需要的一种模式