一、正则的基础概念
正则(Regular Expression):是一个处理字符串的规则
- 1)正则只能用来处理字符串
- 2)处理一般包含两方面:
- A:正则匹配:验证当前字符串是否符合某个规则
- B:正则捕获:把一个字符串中符合规则的字符获取到
学习正则其实就是在学习如何编写规则,每一个正则都是由元字符和修饰符两部分组成
一、创建正则的两种方式
let reg = /^\d+$/g;
//字面量方式let reg2 = new RegExp(''||//, 'g');
//构造函数方式 第一个参数可以放变量- 正则两个斜杠包起来的都是元字符,斜杠后面出现的都是修饰符
二、常用的修饰符
常用的修饰符 | 全称 | 含义 |
---|---|---|
i | ignoreCase | 忽略大小写匹配 |
m | multiline | 多行匹配 |
g | global | 全局匹配 |
// m 修饰符 多行匹配
let str = `
赵州桥
长江大桥
多孔桥
南浦大桥
`
let reg = /桥$/mg;
console.log(str.match(reg)); //["桥", "桥", "桥", "桥"]
复制代码
三、常用的元字符:
1.特殊元字符
\d
0-9之间的一个数字\D
非0-9之间的任意字符\w
数字、字母、下划线中的的任意一个字符/[0-9a-zA-Z_]/
\W
非数字、字母、下划线中的任意字符\s
匹配任意一个空白字符,包括:- \t制表符[tab键四个空格]
- 空格
- \n换行符
// test() 方法用于检测一个字符串是否匹配某个模式.
let str = '1-7p';
let reg = /\b7p/;
console.log(reg.test(str)); //true
console.log(reg.exec(str)); //[7p...]
复制代码
\n
匹配一个换行符 (enter)
let str = 'b7\np';
let reg = /^b7\np$/;
console.log(reg.test(str)); //true
console.log(reg.exec(str)); //["b7↵p"...]
console.log(str.match(reg)); //["b7↵p"...]
复制代码
\r
匹配一个回车符\
转义字符: 有两个作用- 把一个普通字符转义为特出字符,例如
\d
; - 把有特殊含义的转义为普通意思,例如:
\.
此处的点不是任意字符,而是一个小数点
- 把一个普通字符转义为特出字符,例如
.
不仅是小数点,代表除了\n 以外的任意字符
let reg = /^.$/;
console.log(reg.test('n')); //true
console.log(reg.test('1')); //true
console.log(reg.test('\n')); //false
console.log(reg.test('nn')); //false 只能是一位
复制代码
^
以某个元字符开头$
以某个元字符结尾x|y|z
x或者y中的任意一个(x和y是自定义的字母)[xyz]
x或者y或者z中的任意一个(xyz为自定义)[^xyz]
非x\y\z的任意字符[a-z]
获取a-z中的任意一个字符 [0-9] <=> \d[^a-z]
非a-z的任意字符()
正则分组(?:)
当前正则只匹配不捕获(?=)
正向预查(?!)
负向预查
2.量词元字符:让其左边的元字符出现多少次
*
出现0到多个字符?
出现0到1个字符+
出现1到多个字符{n}
出现n个字符{n,}
出现n到多个字符{n,m}
出现n到m个字符
// *可以出现0到多次
let reg = /\d*/;
console.log(reg.test('')); //true
console.log(reg.test('52246')); //true
复制代码
//+ 可以出现1到多次,但是不能一次都不出现
let reg = /\d+/;
console.log(reg.test('')); //false
console.log(reg.test('2')); //true
复制代码
// ?可以出现0-1次
let reg = /^\d?$/; //?可以出现0-1个字符
console.log(reg.test('')); //true
console.log(reg.test('5')); //true
console.log(reg.test('5262')); //false
复制代码
//{n}可以出现n个字符
let reg = /^\d{2}$/;
console.log(reg.test('')); //false
console.log(reg.test('2')); //false
console.log(reg.test('26')); //true
console.log(reg.test('2956')); //false
复制代码
//{n,}可以出现n到多个字符
let reg = /^\d{2,}$/;
console.log(reg.test('')); //false
console.log(reg.test('5')); //false
console.log(reg.test('861')); //true
复制代码
//{n,m}可以出现n次到m个字符
let reg = /^\d{2,4}$/;
console.log(reg.test('')); //false
console.log(reg.test('5')); //false
console.log(reg.test('52')); //true
console.log(reg.test('946')); //true
console.log(reg.test('9411')); //true
console.log(reg.test('55555')); //false
复制代码
3. 普通元字符
只要在正则中出现的元字符(在基于字面量方式创建),除了特殊和有量词的以外,其余的都是普通元字符
四、 加^$
和不加^$
的区别
let reg = /\d+/; //=> 不加^和$,代表字符传中只要包含xxx即可
console.log(reg.test('kl55ijs56k')); //true 包含0-9之间的任意数字
复制代码
let reg1 = /^\d+$/; //=> 加^和$,代表字符传中必须以0-9中的任意数字为开头和结尾
console.log(reg1.test('kl55ijs56k')); //false
console.log(reg1.test('5222')); //true
复制代码
去掉字符串前后空格
//方案一: 获取'a b',去掉前后空格
let str = ' a b ';
//第一个for循环去掉了a前面的空格
for (var i = 0; i < str.length; i++) {
if (str[i] !== ' ') {
//如果循环到字符串中各项不是空格,就强制停止整个循环
break;
}
}
str = str.substring(i);//此时 str用var i为全局变量
//第二个for循环去掉了b后面的空格
for (var k = str.length - 1; k > 0; k--) {
//从最后一位开始找,如果不是空格,就截取第一项到索引那项
if (str[k] !== ' ') {
str = str.substring(0, k + 1);
break;
}
}
console.log(str); //a b 去掉了前后空格
复制代码
//方案二: 获取'a b',去掉前后空格
let str = ' a b ';
str = str.trim(); //字符串方法:去掉字符串前后空格
console.log(str); //a b 去掉了前后空格
复制代码
//方案三: 获取'a b',去掉前后空格
let str = ' a b ';
let reg = /^\s+|\s+$/g; //以空格开头或者以空格结尾
console.log(str.replace(reg, ''));
复制代码
二、[]的细节 & ()的作用
一、中括号的一些特殊细节
1.[]中出现的元字符一般都是代表本身含义的
let reg = /^[.]+$/; //在这里只是小数点
console.log(reg.test('n')); //false
console.log(reg.test('1')); //false
console.log(reg.test('\n')); //false
console.log(reg.test('nn')); //false
console.log(reg.test('.')); //true
复制代码
但也有特殊情况,例如:
let reg = /^[\d]+$/; //在这里依然是表示0-9之间的任意数字
console.log(reg.test('2')); //true
console.log(reg.test('lks')); //false
复制代码
2.中括号出现的两位数并不是两位数,而是两个数字中的任意一个
let reg = /^[18]$/; //只能是1或者8
console.log(reg.test('1')); //true
console.log(reg.test('8')); //true
console.log(reg.test('18')); //false
let reg1 = /[18]/; //包含1或者8就可以
console.log(reg1.test('1')); //true
console.log(reg1.test('8')); //true
console.log(reg1.test('18')); //true
console.log(reg1.test('958524')); //true
复制代码
let reg = /^[13-56]$/; // 不是13~56 而是1或者3~5或者6
console.log(reg.test('1')); //true
console.log(reg.test('8')); //true
console.log(reg.test('6')); //false
复制代码
// 一位数是正常的 从n到m
let reg = /^[2-5]$/;
console.log(reg.test('2')); //true
console.log(reg.test('8')); //false
console.log(reg.test('5')); //true
复制代码
=======
匹配18-65之间的方法:
18-19 1[89] 20-59 [2-5]\d 60-65 6[0-5]
let reg = /^( ( 1[89] ) | ( [2-5]\d ) | ( 6[0-5] ) ) $/;
console.log(reg.test('19'));
//true
需求:编写一个规则,匹配"[object AAA]"
let reg = /^[object .+]$/; console.log(reg.test('[object AAA]')); //true
计算字符串中的字节长度(一个英文字节为1,一个中文为2)
let str = '这个case非常international';
let num = 0;
for (let item of str) {
//[\u4e00-\u9fa5] 中文区间 如果字符串中的各项为中文(即为true)
if (/[\u4e00-\u9fa5]/.test(item)) {
num += 2;
}else{
num += 1;
};
};
复制代码
二、()分组的作用
- 改变默认的优先级
- 分组捕获
- 分组引用
1)改变默认优先级(提权)
//不加小括号的情况
let reg = /^12|14$/; // 12或者14或者以12开头或者以14结尾的都可以
console.log(reg.test('12')); //true
console.log(reg.test('14'));//true
console.log(reg.test('1214'));//true
console.log(reg.test('1258465414'));//true
console.log(reg.test('914'));//true
console.log(reg.test('123'));//true
console.log(reg.test('12ko'));//true
console.log(reg.test('+kj14'));//true
console.log(reg.test('12dsjjkn14'));//true
复制代码
let reg = /^(12|14)$/; // 分组改变默认优先级
console.log(reg.test('12')); //true
console.log(reg.test('14'));//true
console.log(reg.test('1214'));//false
console.log(reg.test('1258465414'));//false
console.log(reg.test('914'));//false
console.log(reg.test('123'));//false
console.log(reg.test('12ko'));//false
console.log(reg.test('+kj14'));//false
console.log(reg.test('12dsjjkn14'));//false
复制代码
let str = '2018---4//---/26//';
let reg = /(\d+)\D+(\d+)\D+(\d+)\D+/
let s = str.replace(reg,function($0,$1,$2,$3){
console.log($0); // 2018---4//---/26//
console.log($1); //2018
console.log($2); //4
console.log($3); //26
return `${$1}年${$2}月${$3}日`
});
console.log(s); //2018年4月26日
复制代码
关于replace的两个参数:请查看文末关于replace的内容
2)分组引用
let reg = /^([a-z])([a-z])\2\1$/; //正则中出现的\1代表和第一个分组出现一模一样的内容
console.log(reg.test('oppo')); //true
console.log(reg.test('poop')); //true
复制代码
编写一个方法:判断字符串中那个数字最多,出现多少次
let str = '437826357384623537463363726573384633278467382';
let min = -Infinity; //定义一个负无穷大的数
str = str.split('').sort().join('');
// 把乱序字符串用空字符串分割成数组,排序数组,再转成字符串,此时字符串为 '222223333333333333444445556666666777777788888'
/*
\d 1个数字
\d\1 2个一样的数字
\d\1+ 2个到多个一样的数字
/(\d)\1+/g 没找到2个以上一样的数字,函数就执行一次
*/
str.replace(/(\d)\1+/g, function ($0, $1) {
// console.log($0); //22222 3333333333333 44444 555 6666666 7777777 88888
// console.log($1); // 2 3 4 5 6 7 8
if (min < $0.length) {
min = $0.length;
let index = $1
};
})
console.log(min, index); // 13 "3"
复制代码
3)分组捕获
正则捕获使用字符串的match
方法(正则exec方法不常用)
- 如果可以匹配,捕获的结果是一个数组,如果不能匹配获取的结果是null
- 如果只在匹配的时候,想要获取大正则中部分信息,我们可以把这部分使用小括号包起来,形成一个分组(即子项),这样在捕获的时候,不仅可以把大正则匹配的信息捕获到,而且还单独的把小分组匹配的部分信息也捕获到了(分组捕获)
- 有时候写小分组不是为了捕获信息,而是为了改变优先级或者进行分组引用,此时我们可以在分组的前面加上
?:
,代表当前分组只匹配不捕获
let str = '2019';
let reg = /(\d)+/;
console.log(str.match(reg));
// ["2019", "9", index: 0, input: "2019", groups: undefined]
// 不仅把大正则的信息捕获到,子项的信息也捕获到
//注意:子项如果包了一个规则,在规则之后有量词,那么结果为最后一个
复制代码
三、常用的正则表达式
一、有效数字:
- 可以出现
+
-
号,可以没有,也可以有一个 - 整数
0
12
9
:一位或者多位数字,一位0-9
,多位数字不能以0
开头 - 小数部分:可能有可能没有,小数点后面至少要有一位数字
//利用正则检测有效数字
let reg = /^[+-]?(\d|[1-9]\d)(\.\d+)?$/
复制代码
二、手机号码
- 11位数字
- 第二位:3456789
- 以1开头
let reg1 = /^1[3456789]\d{9}$/;
console.log(reg1.test('18704366271'));
复制代码
三、中文姓名[\u4E00-\u9FA5]
- 中文汉字
[\u4E00-\u9FA5]{2,}
- 迪丽热巴·迪力木拉提
//中文姓名 1)中文汉字[\u4E00-\u9FA5]{2,} 2)
let reg = /^[\u4E00-\u9FA5]{2,}((·)([\u4E00-\u9FA5]{2,}))?$/;
console.log(reg.test('汤姆')); //true
console.log(reg.test('汤姆·')); //false
console.log(reg.exec('汤姆·')); // null
console.log(reg.test('汤姆·汉克斯')); //true
console.log(reg.exec('汤姆·汉克斯'));
复制代码
四、邮箱
- 数字 字母 下划线 - .
.
和-
不能作为开头,不能连续出现 - 或者 .@
后面(域名):xxx.xx.xx
xxx.xx
xxx.xx.xx.xx
xxx-xxx-xx.xx.xx
let reg = /^\w+([-.]\w)*@[A-Za-z0-9]+([.-])[A-Za-z0-9]+)*(\.[A-Za-z0-9]+)$/
复制代码
五、身份证号码
- 前六位省市区
- 年1800-1899 1900-1999 2000-2019
- 月[01-12] 01-09 10-12
- 日 01-31: 01-09 10-29 30-31
- 最后一位是数字或者x或者X
let reg2 = /^\d{6}((18\d\d)|(19\d\d)|(20[01]\d))(0[1-9]|1[12])(0[1-9]|[12]\d|3[01])\d{3}[\dxX]$/;
console.log(reg2.test('220802199603241523'));
复制代码
四、正则捕获的懒惰性
- 正则匹配:写一个规则验证当前这个字符串和规则是不是匹配
test()
- 正则捕获:把一个字符串中所有和正则相匹配的字符获取到 =>
exec()
test()
- 字符串中的一些方法也能实现正则捕获:
match
split
replace
一、正则捕获的懒惰性
基于exec
可以实现正则捕获
- 1.如果当前字符串和正则不匹配 =>
null
- 2.如果匹配,捕获的结果是一个数组
0
:大正则捕获的内容index
:正则捕获的起始索引input
:原始操作的字符串
- 3.执行一次
exec
只能捕获到第一个和正则匹配的内容,其余匹配的内容还没有捕获到,而且执行多次也无效 => 正则捕获的懒惰性
正则捕获的懒惰性:只能捕获到第一个匹配的内容,剩余的默认捕获不到
let str = 'hello2018hello2019';
let str1 = 'hellohello';
let reg = /\d+/;
console.log(reg.test(str)); //true
console.log(reg.test(str1)); //false
console.log(reg.exec(str1)); // null
console.log(reg.exec(str)); //["2018", index: 5, input: "hello2018hello2019", groups: undefined]
复制代码
二、正则懒惰性产生的原因
- 正则懒惰性的原因:
lastIndex
不变 lastIndex
正则捕获时候,下一次在字符串中开始查找的索引
let str = 'zhufeng2018zhufeng2019';
let reg = /\d+/;
console.log(reg.exec(str)); //=> 2018
console.log(reg.lastIndex); //=> 0
console.log(reg.exec(str)); //=> 2018
console.log(reg.lastIndex); //=>0
// 即使手动修改了lastIndex值 依旧无效
reg.lastIndex = 11;
console.log(reg.lastIndex); //=>0
复制代码
三、正则懒惰性的解决方案
// 解决正则懒惰性:加全局修饰符g
let str = 'zhufeng2018zhufeng2019';
let reg = /\d+/g;
console.log(reg.lastIndex); //=> 0
console.log(reg.exec(str)); //=> 2018
console.log(reg.lastIndex); //=> 11
console.log(reg.exec(str)); //=> 2019
console.log(reg.lastIndex); //=>22
console.log(reg.exec(str)); //=> null
console.log(reg.lastIndex); //=>0
console.log(reg.exec(str)); //=> 2018
复制代码
四、编写一个方法:执行一次即可获取
let str = 'zhufeng2018zhufeng2019yangfan2020qihang2021';
let reg = /\d+/g;
RegExp.prototype.myExecAll = function(str){
// 为了防止出现死循环,我们检测一下正则是否加g,没有加g只把第一次捕获的结果返回即可
if(!this.global){
return this.exec(str);
};
//this:reg 当前操作的正则
//执行exec开始捕获,具体捕获多少次不定,但是一直到捕获不到内容(null)为止,期间把捕获到的内容存储到数组中
let result = [];
let valAry = this.exec(str);
while(valAry){ //=>this.lastIndex < str.length
result.push(valAry[0]); //=>把每次捕获到的结果第一项(具体捕获的内容)存储到容器中
valAry = this.exec(str);
};
return result;
};
console.log(reg.myExecAll(str));
//["2018", "2019", "2020", "2021"]
复制代码
五、利用字符串match方法,把捕获到的字符串统一存储到一个数组中
let str = 'zhufeng2018zhufeng2019yangfan2020qihang2021';
let reg = /\d+/g;
console.log(str.match(reg));
//["2018", "2019", "2020", "2021"]
复制代码
字符串方法:match
实现了自己编写的execAll处理的事情,但也要加全局修饰符g,把所有匹配的内容都捕获到,最后统一存储到一个数组中返回
五、正则捕获的贪婪性
一、分组捕获
match()
方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。
match
实现了自己编写的execAll
处理的事情,但也要加全局修饰符g
,把所有匹配的内容都捕获到,最后统一存储到一个数组中返回
let str = 'zhufeng{2018}zhufeng{2019yangfan{2020}qihang{2021}';
let reg = /\{(?:\d+)\}/g; //大括号有特殊含义:{n}出现的次数
console.log(reg.exec(str));
//["{2018}", "2018", ...]
console.log(str.match(reg)); //=>{2018}", "{2019}", "{2020}", "{2021}
复制代码
- 在正则捕获时,如果正则中存在分组,捕获的时候不仅把大正则匹配到的字符捕获到(数组第一项),而且把小分组匹配的内容也单独抽取出来(数组中的第二项开始就是小分组捕获的内容) => 分组捕获
/\{(?:\d+)\}/g
=>?:
是用来阻止分组捕获内容的 “只匹配不捕获”
match方法的局限性:
console.log(str.match(reg));
//=>{2018}", "{2019}", "{2020}", "{2021}
match方法也有自己的局限性,在正则设置了g
,基于match
捕获的内容只有大正则匹配的,小分组的内容没有单独抽取出来
二、正则捕获的贪婪性
每一次匹配捕获的时候,总是捕获到和正则匹配中最长的内容,例如:2
符合 \d+
2018
也符合 \d+
,但是捕获的是最长的内容 2018
let str = 'zhufeng2018zhufeng2019';
let reg = /\d+/g;
console.log(reg.exec(str)); //["2018", ...]
复制代码
解决方案:在量词元字符后面加?
, 代表的不是出现0-1次,而是取消正则捕获贪婪性
let str = 'zhufeng2018zhufeng2019';
let reg1 = /\d+?/g;
console.log(reg1.exec(str)); // ["2", ...]
复制代码
三、?
在正则中的作用
- 1.量词元字符:出现0-1次
/-?/
让减号出现或者不出现 - 2.取消贪婪性:
/\d+?/
只捕获最短匹配内容 - 3.
?:
只匹配不捕获 -
?=
正向预查
-
?!
负向预查
六、更多的捕获方式
一、关于test()
和exec()
- 基于
test
进行匹配的时候,如果设置了g
,test
匹配也相当于捕获,修改了lastIndex
的值
let str = 'zhufeng2018zhufeng2019';
let reg = /\d+/g;
console.log(reg.test(str)); //true
console.log(reg.lastIndex); //11
console.log(reg.exec(str));//["2019",...]
复制代码
let str = 'zhufeng2018';
let reg = /\d+/g;
console.log(reg.exec(str));//[2018] 把reg.lastIndex值修改了
console.log(reg.exec('zhufeng2018zhufeng2019')); //[2019] 虽然捕获的不是同一个字符串,但是正则是同一个,上一次正则处理的时候修改了它的lastIndex,也会对下一次匹配的字符串产生影响
复制代码
二、捕获方式一:RegExp.$1方式
RegExp.$1
把上一次匹配(test/exec)到的结果获取到,获取的是第一个小分组匹配的内容,大正则匹配的内容无法获取,他是一个全局的值,浏览器中$1只有一个,其他的正则操作也会覆盖这个值,所以这种方式一般不用
let str = 'zhufeng2018peixun2019';
let reg = /(\d+)/g;
console.log(reg.test(str)); //true
console.log(RegExp.$1); //2018
console.log(reg.test(str)); //true
console.log(RegExp.$1); //2019
console.log(reg.test(str));//false
console.log(RegExp.$1); //2019
console.log(reg.test(str));//true
console.log(RegExp.$1); //2018
复制代码
三、捕获方式二:replace
replace:实现正则捕获的方法(本身是字符串替换)
// 需求:把所有的'zhufeng'替换成'zhufengpeixun'
let str = 'zhufeng2018zhufeng2019';
let reg = /(\d+)/g;
str = str.replace('zhufeng','zhufengpeixun'); //一次只能替换一个,第二次还是从索引[0]开始替换
复制代码
- 真实项目中,需要基于正则来替换
let str = 'zhufeng2018zhufeng2019';
str = str.replace(/zhufeng/g,'zhufengpeixun');
console.log(str); //zhufengpeixun2018zhufengpeixun2019
复制代码
四、replace原理
//不常用
let str = 'zhufeng{val:2018}zhufeng{val:2019}';
reg = /\{val:(\d+)\}/g;
str = str.replace(reg,'#'); // 用reg正则和str字符进行匹配,匹配几次就替换几次,每一次都是当前“大正则”匹配的结果用第二个传递的字符串替换掉了
console.log(str); //zhufeng#zhufeng#
复制代码
//不常见
let str = 'zhufeng{val:2018}zhufeng{val:2019}';
reg = /\{val:(\d+)\}/g;
str = str.replace(reg,'$1'); // $1不是拿这个字符替换掉大正则匹配的内容,此处的$1代表第一个分组匹配的内容,等价于 RegExp.$1
console.log(str); //zhufeng2018zhufeng2019
复制代码
原理:string.replace(要替换的字符串||正则,替换成什么||函数);
- 1.reg和str匹配多少次,函数就被触发执行多少次,而且传递了一些参数信息值
- 2.每一次arg存储的信息和执行exec捕获的信息相似(内置原理:每一次正则匹配的结果,都把函数执行,然后基于exec把本次匹配的信息捕获到,然后把捕获的信息传递给这个函数)
- 3.每一函数返回的内容是什么,就把当前大正则匹配的内容替换成什么
//常用
let str = 'zhufeng{val:2018}zhufeng{val:2019}';
reg = /\{val:(\d+)\}/g;
str = str.replace(reg,(...arg) =>{
console.log(arg);
return 'AA';
});
console.log(str);//zhufengAAzhufengAA
复制代码
关于replace中的的两个参数:
-
当第二个参数为函数的时候(默认情况下)
- 函数的第一个参数就是每次匹配到的结果
- 函数的第二个参数index 正则捕获的起始索印
- 函数的第三个参数input 原始操作的字符串
- 函数的第四个(及以后)groups 参数undefined
-
2.如果有小括号提权,则:
- 函数的第一个参数就是每次匹配到的结果
- 函数的第二个参数 第一个小括号匹配的内容
- 函数的第三个参数 第二个小括号匹配的内容
- ...以此类推,直到所有的小括号匹配完毕
- 匹配完毕之后的参数依次为index,input,undefined
-
此函数必须要有return,不然默认为undefined
-
多个小括号嵌套的情况:
/((\d+)\D+(\d+))\D+(\d+)\D+/
- 从左向右,第一个外层小括号为第一个,第一个外层小括号内的第一个小括号为第二个,第一个外层小括号内的第二个小括号为第三个,第二个外层小括号为第四个,以此类推
let str = '2018---4//---/26//';
let reg = /(\d+)\D+(\d+)\D+(\d+)\D+/
let s = str.replace(reg,function($0,$1,$2,$3){
console.log($0); // 2018---4//---/26//
console.log($1); //2018
console.log($2); //4
console.log($3); //26
return `${$1}年${$2}月${$3}日`
});
console.log(s); //2018年4月26日
复制代码
// 用*替换指定字
let str = '为人民服务,为人民奋斗,为人民努力'
let s = str.replace(/服务|奋斗|努力/g,function($0,$1){
let temp = '';
for (let i = 0; i < $0.length; i++) {
temp += '*';
};
console.log($0); //服务 奋斗 努力
return temp
})
console.log(s); // 为人民**,为人民**,为人民**
复制代码