如何提取文本自定义标签并匹配应用到拆分后的句子片段?
实现方案
该需求可实现,核心思路是先解析原带标签句子的标签位置与纯文本的映射关系,再按拆分片段的位置对应回填标签即可。
前置修正
你原有的标签移除函数正则写得不准确,正确的标签匹配规则应为/\[\/?t\d+\]/g,可直接匹配所有[tn]和[/tn]格式的标签。
完整实现代码
// 解析带标签句子,返回纯文本和所有标签的位置信息 function parseTags(taggedStr) { // 统一处理所有连续空白为单个空格,避免原句换行导致位置偏移 const processedTagged = taggedStr.replace(/\s+/g, ' ') const tagRegex = /\[t(\d+)\](.*?)\[\/t\1\]/g const tags = [] let pureText = '' let lastIndex = 0 let match while ((match = tagRegex.exec(processedTagged)) !== null) { // 累加标签前的纯文本 const beforeText = processedTagged.slice(lastIndex, match.index) pureText += beforeText // 记录标签在纯文本中的起止位置 const tagStart = pureText.length const tagContent = match[2] pureText += tagContent const tagEnd = pureText.length tags.push({ start: tagStart, end: tagEnd, tNum: match[1], content: tagContent }) lastIndex = match.index + match[0].length } // 累加最后剩余的纯文本 pureText += processedTagged.slice(lastIndex) return { pureText, tags } } // 为拆分后的片段回填标签 function addTagsToParts(taggedSentence, parts) { const { pureText, tags } = parseTags(taggedSentence) // 校验拆分片段拼接后与原纯文本是否一致,避免拆分错误 const joinedParts = parts.join('').replace(/\s+/g, ' ') if (joinedParts !== pureText) { throw new Error('拆分片段拼接后与原文本不匹配,请检查拆分规则') } let currentOffset = 0 return parts.map(part => { const processedPart = part.replace(/\s+/g, ' ') const partStart = currentOffset const partEnd = currentOffset + processedPart.length currentOffset = partEnd // 筛选和当前片段范围重叠的标签 const overlappingTags = tags.filter(tag => tag.start < partEnd && tag.end > partStart ) let result = processedPart // 倒序插入标签,避免前序插入改变后续位置 overlappingTags.sort((a, b) => b.start - a.start).forEach(tag => { // 计算标签在当前片段内的相对位置 const relStart = Math.max(0, tag.start - partStart) const relEnd = Math.min(processedPart.length, tag.end - partStart) // 先插闭合标签,再插开始标签 result = result.slice(0, relEnd) + `[/t${tag.tNum}]` + result.slice(relEnd) result = result.slice(0, relStart) + `[t${tag.tNum}]` + result.slice(relStart) }) return result }) } // 测试用例 const sentence = `[t1]Sometimes[/t1] that's [t2]just the way[/t2] it has to be. Sure, there were [t3]probably[/t3] other options, but he didn't let them [t4]enter his mind[/t4]. It was done and that was that. It was just the way [t5]it[/t5] had to be.` const parts = [ "Sometimes that's just the way", "it has to be", "Sure,", "there were probably other options,", "but he didn't let them enter his mind.", "It was done and that was that.", "It was just the way it had to be." ] console.log(addTagsToParts(sentence, parts)) // 输出结果和你给出的expectedOutput完全一致
注意事项
- 要求输入的
parts必须是原文本按顺序连续拆分的,不能调整顺序、遗漏或新增内容,否则会触发匹配错误 - 支持标签跨拆分片段的场景,会自动把标签对应拆分到两个片段中
内容的提问来源于stack exchange,提问作者アリ・ナディム
相关产品推荐
相关产品推荐

