限定符
- ? 代表?前面的字符要出现一次和零次
- * 代表*前面的字符可以没有也可以出现多次
- + 代表+前面的字符要出现一次以上
- {} 代表前面的字符出现的范围 比如ab{2,4}c 就会匹配abbc abbbc abbbbc
- () ()括起来的字符代表一个整体 比如(ab)+ 代表ab这个整体要出现一次以上
或运算符
- | 假如我要匹配a cat 或者a dog 我就要写成 a (cat|dog)
字符类
-
[] [abc] 等价于(a|b|c) 方括号里面的内容代表要求匹配的字符只能取自于它 们,我们可以在方括号里指定字符的范围 比如[a-z]代表所有的小写英文字符[a-zA-Z]代表所有的英文字符 [a-zA-Z0-9]代表所有的英文字符和数字
-
^ ^叫脱字符 代表取反 比如[^0-9] 代表所有的非数字字符(包括换行符) 必须要写在[]里面才是取反的意思
元字符
- \d 代表数字字符
- \w 代表单词字符 英文,数字及下划线
- \s 代表空白符 包含Tab和换行符
- \D 代表非数字字符
- \W 代表非单词字符
- \S 代表非空白字符
- . 代表任意字符,但不包含换行符
- ^ 匹配行首 比如^a 只会去匹配行首的a
- $ 匹配行尾
- \b 代表单词边界 ,不占位置,不代表实际字符
- \ 转义字符 既能取消元字符的特殊含义,也能赋予普通字符特殊功能 比如. 就是匹配. 这个点号
- / 定届符 /正则表达式内容/标志 /abc/ 匹配 "abc" /\d+/g 匹配一个或多个数字,全局搜索 就是匹配成功了一个 要接着匹配 如果没有g的话 匹配成功一个就停止了
贪婪与懒惰匹配
<.+> 贪婪匹配-尽可能的匹配多个字符
输入: <div>hello</div><p>world</p>
匹配结果: <div>hello</div><p>world</p>
整个字符串都被匹配了,因为它从第一个 < 开始,一直匹配到最后一个 >
<.+?>懒惰匹配-尽可能匹配更短的字符串
输入: <div>hello</div><p>world</p>
匹配结果: <div> 和 <p>
找到了两个独立的标签,而不是一个长的匹配
快手校招一面代码题
背景是小编的项目用到了marked库 然后面试官就让我实现一个关键字高亮的一个效果 给了两个示例让自己编写一个函数实现 如果是你们会怎么实现
示例1 输入 str = '我熟悉react,vue,es6'
关键字数组 keyWords = ['react','vue','es6']
预期输出 我熟悉<span>react</span>、<span>vue</span>及<span>es6</span>
示例2 输入 str = '我熟悉vue,es6'
关键字数组 keyWords = ['react','vue','vuejs','es6']
预期输出 我熟悉<span>vuejs</span>及<span>es6</span> //vue匹配的是vuejs 匹配长的那一个
小编也是不出所料没搞出来哈哈 面试官最后跟我说可以用正则表达式来做 在此之前压根不会正则表达式 我都是用ai直接给我生成 因此写了这篇文章来鞭挞自己,下面是小编下来写的答案,仅供参考
function highlightKeywords(str, keywords) {
const sortedKeys = [...new Set(keywords)]
const pattern = new RegExp(sortedKeys.join('|'), 'g');
let result = str.replace(pattern, match => `<span>${match}</span>`);
// 直接处理连接符逻辑
result = result.replace(/,/g, '、');
// 找到最后一个顿号替换为"及"
const lastCommaIndex = result.lastIndexOf('、');
if (lastCommaIndex !== -1) {
result = result.substring(0, lastCommaIndex) + '及' + result.substring(lastCommaIndex + 1);
}
let newKeys = sortedKeys.sort()
//对于第二个例子排序后为 ['es6','react','vue','vuejs']
for (let i = 0; i < newKeys.length; i++) {
if (result.includes(newKeys[i]) && i < newKeys.length - 1
&& newKeys[i + 1].startsWith(newKeys[i])) {
result = result.replace(newKeys[i], newKeys[i + 1])
}
}
return result;
}
// 测试
console.log(highlightKeywords('我熟悉react,vue,es6', ['react', 'vue', 'es6']));
// 输出:我熟悉<span>react</span>、<span>vue</span>及<span>es6</span>
console.log(highlightKeywords('我熟悉vue,es6', ['react', 'vue', 'vuejs', 'es6']));
// 输出:我熟悉<span>vuejs</span>及<span>es6</span>