目录
一、介绍
抖音"封神榜"大家可都知道?大名鼎鼎的梅楼封是抖音玩家最害怕的人物,在抖音玩家中,谁都不想在封神榜中留名,玩家只要说话违规,那么就有可能入住封神榜,然后各种悲催的日子就来了,想要不被梅楼封关注,就要学会说话的套路,避免被封杀。
今天我们来到蓝桥云课,在这里让你体验一把梅楼封的权利,炫耀一下自己,杀杀不遵守规则玩家的锐气。好了,废话不多说,现在就带你坐镇蓝桥云课,体验梅楼封的一天!
二、目标
玩家说话没技巧,让你感到很愤怒,要求封装一个方法,将该玩家封杀:
1.函数入参要求:
第一个参数为字符串(任意字符串)。
第二个参数为脱敏规则,可以是字符串,也可以是数组。
第三个参数是字符串,表示用什么来占位脱敏文字(默认为:*)。
第四个参数是:是否将手机号(11 位数字)进行脱敏,默认为 true(规则是:保留前三位和后三位,中间脱敏占位)。
// 函数传递参数,输出 {ids: [1], newStr: '开*每一天'}
toDesensitization("开心每一天", ["心"], "*", false);
2.出参要求:
- 第一个参数不存在返回 null。
- 第一个参数存在,第二个参数不存在,返回原字符串。
- 第一个参数和第二个参数都存在,返回脱敏后的新字符串以及被脱敏的文本位置,返回格式是一个对象( 注意:无论手机号是否脱敏处理,都不会返回手机号的被脱敏时的位置 ),格式如下:
{
"ids": [],
"newStr": ""
}
三、输出示例
1.示例一
输入内容
人的一生,好不好只有自己知道,乐不乐只有自己明白。快乐是一种心情,一种自然、积极向上的心态。在平凡之中寻求快乐,在磨难之中寻求快乐,在曲折之中需求快乐。
规则为:“向上”
脱敏占位符为: “*”
输出返回
{
"ids": [40],
"newStr": "人的一生,好不好只有自己知道,乐不乐只有自己明白。快乐是一种心情,一种自然、积极**的心态。在平凡之中寻求快乐,在磨难之中寻求快乐,在曲折之中需求快乐。"
}
2.示例二
输入内容
不论这个世界多么糟糕,你的世界一定要精彩;不论人心多么黑暗,你的内心一定要明亮。不要用糟糕去对付糟糕,不要用黑暗去对付黑暗。心里充满阳光,世界就光明无比;心里充满感恩,世界因此灿烂。请记住:你的付出决定你的未来,你的汗水记得你的成就,你的态度决定你的一切.
规则为:[‘糟糕’,‘记得’, ‘定’]
脱敏占位符为: *
输出返回:
{
"ids": [8, 43, 48, 110, 16, 35, 100, 122],
"newStr": "不论这个世界多么**,你的世界一*要精彩;不论人心多么黑暗,你的内心一*要明亮。不要用**去对付**,不要用黑暗去对付黑暗。心里充满阳光,世界就光明无比;心里充满感恩,世界因此灿烂。请记住:你的付出决*你的未来,你的汗水**你的成就,你的态度决*你的一切。"
}
3.示例三
输入内容
今天有人宣传要手机号等个人信息,可是骚扰电话太多了,不想泄漏隐私,哎,想来是熟人,没办法,我的手机号是 15698254321,你一定要记好了。
规则为:[‘宣传’,‘骚扰’,‘私’]
脱敏占位符为: *
是否脱敏手机号:true
输出返回:
{
"ids": [4,18,31],
"newStr": "今天有人**要手机号等个人信息,可是**电话太多了,不想泄漏隐*,哎,想来是熟人,没办法,我的手机号是 156*****321,你一定要记好了。"
}
4.示例四
输入内容
来好吗!怎样一向不打电话给我啊。知道吗?我还是我,但号码已经换成了 15273773888,多联络啊。
规则为:‘号码’
脱敏占位符为: *
是否脱敏手机号:true
输出返回:
{
"ids": [26],
"newStr": "来好吗!怎样一向不打电话给我啊。知道吗?我还是我,但**已经换成了 152*****888,多联络啊。"
}
5.示例五
输入内容
uofjjflsjhahf废旧塑料ffjsljfs
规则为:‘jj’
输出返回:
{
"ids": [3],
"newStr": "uof**flsjhahf废旧塑料ffjsljfs"
}
四、待完善代码
/**
* @description:
* @param {*} str
* @param {*} rule
* @param {*} symbol
* @param {*} dealPhone
* @return {*}
*/
const toDesensitization = (str, rule, symbol = '*', dealPhone = true) => {
}
五、知识点
1.正则表达式
-
两种写法
- const reg =/正则表达式内容/参数
- const reg=newReg(‘正则表达式内容’,''参数")
-
参数:
- g :表示全局(global)模式,即模式将被应用于所有字符串,而非在发现第一个匹配项时立即停止;
- i :表示不区分大小写(case-insensitive)模式,即在确定匹配项时忽略模式与字符串的大小写;
- m :表示多行(multiline)模式,即在到达一行文本末尾时还会继续查找下一行中是否存在与模式匹配的项。
2.split方法
String split() 方法
- str.split() 方法将字符串拆分为子字符串数组。
- split() 方法返回新数组,不会更改原始字符串。
- 如果 (" ") 用作分隔符,则字符串在单词之间进行拆分
3.test方法
RegExp test() 方法
- reg.test() 方法测试字符串中的匹配项。
- 如果找到匹配项,则返回 true,否则返回 false。
4.match方法
String match() 方法
- str.match() 方法将字符串与正则表达式进行匹配。
- match() 方法返回包含匹配项的数组。
- 如果未找到匹配项,则 match() 方法返回 null。
- 如果找到了匹配项,则返回
[
'匹配文本'//该数组的第 0 个元素存放的是匹配文本
index: 3,//index 属性声明的是匹配文本的起始字符在 string 中的位置
input: 'uofjjflsjhahf废旧塑料ffjsljfs',//input 属性声明的是对 string 的引用。
]
以上说明适用于非全局匹配的正则表达式
如果 regexp 具有标志 g,则 match() 方法将执行全局检索,找到 string 中的所有匹配子字符串。若没有找到任何匹配的子串,则返回 null。如果找到了一个或多个匹配子串,则返回一个数组。不过全局匹配返回的数组的内容与前者大不相同,它的数组元素中存放的是 string 中所有的匹配子串,而且也没有 index 属性或 input 属性。
5.matchAll方法
String match() 方法
- 那么当我们需要全局匹配且需要获取index和input属性怎么办?可以使用mathchAll方法。
- matchAll() 方法返回一个包含所有匹配正则表达式的结果及其分组捕获组的迭代器
- 返回值:一个迭代器,可以使用for…of…,数组新增的扩展符(…)或Array.from()实现功能
注意:需要在正则表达式中写明全局匹配(g)否则会报错,以及注意要将返回值转化为数组
6.slice方法
Array slice() 方法
- slice() 方法以新的数组对象,返回数组中被选中的元素。
- slice() 方法选择从给定的 start 参数开始的元素,并在给定的 end 参数处结束,但不包括。(左闭右开)
注释:slice() 方法不会改变原始数组。
7.replace() 方法
String replace() 方法
- replace() 方法在字符串中搜索值或正则表达式。
- replace() 方法返回已替换值的新字符串。
- eplace() 方法不会更改原始字符串。
如果您替换值,则只会替换第一个实例。如需替换所有实例,请使用带有 g 修饰符集的正则表达式。
8.repeat方法
String repeat(count) 方法
str.repeat()方法示例:
let str ='*'
str=str.repeat(2)
console.log(str)//输出 **
- count:重复次数
- 不会改变原对象
六、答案
const toDesensitization = (str, rule, symbol = '*', dealPhone = true) => {
//题目要求返回的数据格式
let results = {
ids: [],
newStr: str,
}
//第一个参数不存在返回 null。
if (!str) {
return null
}
//第一个参数存在,第二个参数不存在,返回原字符串。
if (str && !rule) return str
//如果输入的是字符串类型的 那么将其转换为数组
if (typeof rule === 'string') {
//根据逗号分割字符串
rule = rule.split(',')
}
//for of 循环遍历数组 取的是value
for (let item of rule) {
//正则表达式 全局匹配
let reg = new RegExp(`${
item}`, 'g')
if (reg.test(str)) {
//获取所有匹配的索引 将他们添加到ids
[...str.matchAll(reg)].forEach((item) => {
results.ids.push(item.index)
})
//注意:如果reg没有选择全局匹配 那么调用matchAll会报错
//本来replace方法只能替换第一个匹配的字符串,但是如果正则表达式中设置了全局标志g,那么replace方法就会替换所有匹配的子字符串。
results.newStr = results.newStr.replace(reg, symbol.repeat(item.length))
}
}
if (dealPhone) {
//手机号替换
const reg = /1\d{10}/
if (reg.test(str)) {
let temp = str.match(reg)[0]
temp = temp.slice(3, -3)
results.newStr = results.newStr.replace(temp, symbol.repeat(temp.length))
}
}
return results
}