-
定义:replace() 方法返回一个新字符串,其中一个、多个或所有匹配的 pattern 被替换为 replacement
-
语法:
replace(pattern, replacement)【 1、pattern:string | RegExp 2、replacement:string | Function 】 -
用法梳理:
- 1、基础用法: replacement 是个字符串,这是最基础的常见的用法,本文不在敖述
const paragraph = "I think Ruth's dog is cuter than your dog!"; console.log(paragraph.replace("Ruth's", 'my')); // Expected output: "I think my dog is cuter than your dog!" const regex = /Dog/i; console.log(paragraph.replace(regex, 'ferret')); // Expected output: "I think Ruth's ferret is cuter than your dog!"-
2、高阶用法:replacement 是个函数
- 在只有一个匹配项时,这个函数会收到3个参数:与整个模式匹配的字符串、匹配项在字符串中的开始位置,以及整个字符串。在有多个捕获组的情况下,每个匹配捕获组的字符串也会作为参数传给这个函数,但最后两个参数还是与整个模式匹配的开始位置和原始字符串。这个函数应该返回一个字符串,表示应该把匹配项替换成什么
-
那么怎么区分是3个参数还多个参数呢?
-
正确的理解是:
2-1、当pattern为正则,无分组,那么只有一个匹配,那么replacement就只会有三个参数;其定义为:
function replacer(match, offset, originStr) {return replacement;}【 无分组,只有三个参数 】function upperToHyphenLower(match, offset, string) { // Remark: 这个地方match是匹配值,offset是偏移量,string是原字符串 // Expected output: 你将看到的匹配项 S 5 superStar console.log("你将看到的匹配项", match, offset, string) return (offset > 0 ? "-" : "") + match.toLowerCase(); } // Expected output: "super-star" console.log("superStar".replace(/[A-Z]/g, upperToHyphenLower))2-2、当pattern为正则,且有捕获分组时,那么就是有多个参数;捕获组的个数有多少,额外参数就有多少,其定义为:
function replacer(match, p1, p2, /* …, */ pN, offset, string, groups) {return replacement;}【 其中p1, p2 .... pn 即为各个捕获组数据,和正则中的1, n)对齐 】function upperToHyphenLower(match, p1, offset, string) { // Remark: 这个地方match是匹配值,p1是捕获组的值,offset是偏移量,string是原字符串 // Expected output: 你将看到的匹配项 S S 5 superStar console.log("你将看到的匹配项", match, p1, offset, string) return (offset > 0 ? "-" : "") + match.toLowerCase(); } // Expected output: "super-star" console.log("superStar".replace(/([A-Z])/g, upperToHyphenLower))
-
- 在只有一个匹配项时,这个函数会收到3个参数:与整个模式匹配的字符串、匹配项在字符串中的开始位置,以及整个字符串。在有多个捕获组的情况下,每个匹配捕获组的字符串也会作为参数传给这个函数,但最后两个参数还是与整个模式匹配的开始位置和原始字符串。这个函数应该返回一个字符串,表示应该把匹配项替换成什么
-
需要注意的事:
-
1、对于正则的分组,有如下几种情况需要排查:
-
( 被转义过的括号不算
-
(?:) 非捕获组的不算
-
[(] 放在方括号里面的小括号也不算,这也属于被转义过。
这些情况下,正则分组标识符号 “(” 无效,被认为是无效分组
// 无效分组,视为无分组,参数依然是三个 function upperToHyphenLower(match, offset, string) { // Remark: 这个地方match是匹配值,offset是偏移量,string是原字符串 // 正则全局,匹配多次,函数多次调用,依次替换 // Expected output: 你将看到的匹配项 (A) 3 you(A)re(S)uper(S)tar // Expected output: 你将看到的匹配项 (S) 8 you(A)re(S)uper(S)tar // Expected output: 你将看到的匹配项 (S) 15 you(A)re(S)uper(S)tar console.log("你将看到的匹配项", match, offset, string) return (offset > 0 ? "-" : "") + match.toLowerCase(); } // Expected output: you-(a)re-(s)uper-(s)tar console.log("you(A)re(S)uper(S)tar".replace(/\([A-Z]\)/g, upperToHyphenLower)) /********************************************************************/ // 无效分组,视为无分组,参数依然是三个 function upperToHyphenLower(match, offset, string) { // Remark: 这个地方match是匹配值,offset是偏移量,string是原字符串 // 正则全局,匹配多次,函数多次调用,依次替换 // Expected output: 你将看到的匹配项 (A) 3 you(A)re(S)uper(S)tar // Expected output: 你将看到的匹配项 (S) 8 you(A)re(S)uper(S)tar // Expected output: 你将看到的匹配项 (S) 15 you(A)re(S)uper(S)tar console.log("你将看到的匹配项", match, offset, string) return (offset > 0 ? "-" : "") + match.toLowerCase(); } // Expected output: you-(a)re-(s)uper-(s)tar console.log("you(A)re(S)uper(S)tar".replace(/[(][A-Z][)]/g, upperToHyphenLower)) /********************************************************************/ // 无效分组,视为无分组,参数依然是三个 function upperToHyphenLower(match, offset, string) { // Remark: 这个地方match是匹配值,offset是偏移量,string是原字符串 // 正则全局,匹配多次,函数多次调用,依次替换 // Expected output: 你将看到的匹配项 (A) 4 you(A)re(S)uper(S)tar // Expected output: 你将看到的匹配项 (S) 9 you(A)re(S)uper(S)tar // Expected output: 你将看到的匹配项 (S) 16 you(A)re(S)uper(S)tar console.log("你将看到的匹配项", match, offset, string) return (offset > 0 ? "-" : "") + match.toLowerCase(); } // Expected output: you(-a)re(-s)uper(-s)tar console.log("you(A)re(S)uper(S)tar".replace(/(?:[A-Z])/g, upperToHyphenLower)) -
-
2、当replacement是函数时,如果第一个参数中的正则表达式是全局的,那么为了替换每个完全匹配的字符串,该函数将被多次调用
这种情况下,无论回调函数时多少个参数,都会多次执行
// 无分组,三个参数时 function upperToHyphenLower(match, offset, string) { // Remark: 这个地方match是匹配值,offset是偏移量,string是原字符串 // 正则全局,匹配多次,函数多次调用,依次替换 // Expected output: 你将看到的匹配项 A 3 youAreSuperStar // Expected output: 你将看到的匹配项 S 6 youAreSuperStar // Expected output: 你将看到的匹配项 S 11 youAreSuperStar console.log("你将看到的匹配项", match, offset, string) return (offset > 0 ? "-" : "") + match.toLowerCase(); } // Expected output: "you-are-super-star" console.log("youAreSuperStar".replace(/[A-Z]/g, upperToHyphenLower)) /********************************************************************/ // 有分组,多个参数时 function upperToHyphenLower(match, p1, offset, string) { // Remark: 这个地方match是匹配值,p1是捕获组的值,offset是偏移量,string是原字符串 // 正则全局,匹配多次,函数多次调用,依次替换 // Expected output: 你将看到的匹配项 A A 3 youAreSuperStar // Expected output: 你将看到的匹配项 S S 6 youAreSuperStar // Expected output: 你将看到的匹配项 S S 11 youAreSuperStar console.log("你将看到的匹配项", match, p1, offset, string) return (offset > 0 ? "-" : "") + match.toLowerCase(); } // Expected output: "you-are-super-star" console.log("youAreSuperStar".replace(/([A-Z])/g, upperToHyphenLower))
-
-
使用场景:
-
低代码和泛低代码工程
- 低代码本质上,是将用户配置的字符串配置,给予转换执行,低代码工程注定对字符串的操作比较多,有些就会牵涉到高级一点的正则匹配替换
// lowcode-engine use demo const RE_CAMEL = /[A-Z]/g; const RE_HYPHEN = /[-\s]+(.)?/g; function hyphenate(str: string): string { return str.replace(RE_CAMEL, w => `-${w}`).toLowerCase(); } function camelize(str: string): string { return str.replace(RE_HYPHEN, (m, w) => (w ? w.toUpperCase() : '')); }
-
-
参考: