无脑的需求
又是一个编排的需求来了,我需要一个搜索框,百度那样的,你看着办吧。(手打黑人问号)
做不出来,简单点!!!!!
好的!我需要一个关键词匹配的输入框,以特定符号作为分割,对返回的数据做全文高亮显示。
以上就是一个需求的诞生!!!如下
这是一段测试文字,需要通过关键词匹配,已测试中通过等等等等
输入关键词:测试,通过,已测试,测试中
输出匹配结果:这是一段测试
文字,需要通过
关键词匹配,已测试中通过
等等等等
需求分析来了
首先我们想到的肯定是关键词替换然后用有了以下代码
const text = '这是一段测试文字,需要通过关键词匹配,已测试中通过中等等等等'
const matchArr = ['测试', '通过', '已测试', '测试中']
const regex = new RegExp(`(${matchArr.join('|')})`, 'g')
const highlightedText = text.replace(regex, '<em>$1</em>')
console.log(highlightedText) // 这是一段<code>测试</code>文字,需要<code>通过</code>关键词匹配,<code>已测试</code>中<code>通过</code>等等等等
这是一段测试
文字,需要通过
关键词匹配,已测试
中通过
等等等等
这样匹配的内容虽然大部分都相同,但是与我们想要的肯定不一样了啊。
这是一段测试
文字,需要通过
关键词匹配,已测试中通过
等等等等
因为我们想要的是内容是如上内容,显然已测试中通过这个没有匹配上
所以这样是行不通的,如过只是单独的匹配这样写是没有问题的,但是多关键词这样写就会出现相连的词语重复性的问题。
现在问题已经出现了就要解决不能相连的问题了,然后我想到了leetCode中的一个算法题目,合并区间
如上,只要我能获取到下标区间,就能进行算法来合并区间,就可以解决(已测试
中通过)
不能相连的问题了!(因为本人使用vue所以以下会出现vue代码,请自行进行优化)
mounted() {
const needMatch = '这是一段测试文字,需要通过关键词匹配,已测试中通过等等等等'
const keyword = '测试,通过,已测试,测试中'
const indices = this.searchMatch(keyword, needMatch)
}
methods: {
searchMatch(keyword, needMatch) {
const keywordData = keyword && keyword.split(',') || [] // 当搜索为空时
const indices = [] // 存储下标位置
keywordData.forEach(item => {
let index = needMatch.indexOf(item)
while (index !== -1) { // 在整个文本中查找 item 的下标位置,直到找不到为止
indices.push([index, index + item.length - 1])
index = needMatch.indexOf(item, index + 1) // 接着在查找到的下标之后框框下一个
}
})
return indices // [[4, 5], [20, 21], [11, 12], [23, 24], [19, 21], [20, 22]]
}
}
这个时候我们就已经拿到了我们想要的下标了,然后就需要合并区间了!
mounted
const mergeIndices = this.merge(indices) // [[4, 5], [11, 12], [19, 22], [23, 24]]
methods
merge(intervals) {
if (!intervals || !intervals.length) return []
intervals.sort((a, b) => a[0] - b[0])
const newDate = [intervals[0]]
for (let i = 1; i < intervals.length; i++) {
if (newDate[newDate.length - 1][1] >= intervals[i][0]) {
newDate[newDate.length - 1][1] = Math.max(newDate[newDate.length - 1][1], intervals[i][1])
} else {
newDate.push(intervals[i])
}
}
return newDate
},
最后当我们获取到了最后需要的数据后,就需要去进行高亮代码展示了
mounted
const highlightedText = this.highlighted(mergeIndices, needMatch) // 这是一段<code>测试</code>文字,需要<code>通过</code>关键词匹配,<code>已测试中</code><code>通过</code>等等等等
methods
highlighted(mergeIndices, needMatch) {
let highlightedText = '' // 初始化高亮后的文本为空字符串
let startIndex = 0 // 记录每一次高亮结束的位置,需要在下一次高亮的时候从这里开始
mergeIndices.forEach(([start, end]) => {
// console.log(startIndex, start, text.substring(startIndex, start))
highlightedText += needMatch.substring(startIndex, start) // 将高亮前的部分添加到高亮后的文本中
highlightedText += `<code>${needMatch.substring(start, end + 1)}</code>` // 将高亮的部分添加到高亮后的文本中
startIndex = end + 1 // 更新下一次高亮的起始位置
})
highlightedText += needMatch.substring(startIndex) // 将高亮后的文本的剩余部分添加到高亮后的文本中
return highlightedText
},
以上就是全过程了,希望对你有所帮助。
end