You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于用户自定义格式令牌准确解析字符串提取信息?

问题描述

需要根据自定义令牌格式的模板,从输入字符串中提取对应信息,示例如下:

  • 模板格式:#artist# - #song# [#id#]
  • 输入字符串:Taylor Swift - Anti-Hero [ID123]
    目标是正确提取艺术家(artist)、歌曲(song)与ID信息。

当前实现代码如下:

let format = "#artist# - #song# [#id#]";
let split = format.split(/#\w*#/);

for(let i = 0; i < split.length; i++) {
  if (split[i] !== '') {
    let rep = split[i].split('').map(x => `\\${x}`).join('');
    format = format.replace(split[i], rep);
  }
}
format = format.replace('#artist#', '([\\w\\s]*)').replace('#song#', '([\\w\\s]*)').replaceAll('#ignore#', '([\\w\\s]*)');
let test = new RegExp(format, 'g');
let res = 'Taylor Swift - AntiHero [ID123]'.matchAll(test);

存在以下问题:

  • 当歌曲名包含连字符(如Anti-Hero)时,使用([\w\s]*)会因为连字符不在匹配范围内导致匹配失败
  • 如果ID外围的方括号被移除(此时方括号属于ID内容),原代码会解析失效
  • 格式替换过程中存在匹配冲突,比如空格会匹配已转义替换的' - '部分
  • 非单词/空格的字符会破坏令牌的搜索逻辑
优化实现方案

可以采用先解析模板中的静态片段与令牌,再动态构建正则表达式的方式解决上述问题,具体实现如下:

function parseWithTemplate(template, input) {
  // 匹配所有令牌和静态文本片段
  const tokenRegex = /(#\w+#)|([^#]+)/g;
  const regexParts = [];
  const tokenNames = [];
  let match;
  
  while ((match = tokenRegex.exec(template)) !== null) {
    if (match[1]) {
      // 提取令牌名称(去除前后#)
      const name = match[1].slice(1, -1);
      tokenNames.push(name);
      // 添加非贪婪捕获组,适配任意字符匹配
      regexParts.push('(.*?)');
    } else {
      // 转义静态文本中的正则特殊字符(如-、[、]等)
      const escapedText = match[2].replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
      regexParts.push(escapedText);
    }
  }
  
  // 构建完整正则,开启单行模式确保.能匹配换行符
  const fullRegex = new RegExp(`^${regexParts.join('')}$`, 's');
  const matchResult = input.match(fullRegex);
  
  if (!matchResult) return null;
  
  // 将捕获结果与令牌对应,返回结构化对象
  const result = {};
  tokenNames.forEach((token, index) => {
    result[token] = matchResult[index + 1].trim(); // 可选:去除内容前后空格
  });
  
  return result;
}

// 测试用例
const template = "#artist# - #song# [#id#]";
const input1 = "Taylor Swift - Anti-Hero [ID123]";
const input2 = "Taylor Swift - Anti-Hero ID123]"; // 移除左侧方括号
const input3 = "Taylor Swift - Anti-Hero [ID123"; // 移除右侧方括号

console.log(parseWithTemplate(template, input1)); 
// { artist: 'Taylor Swift', song: 'Anti-Hero', id: 'ID123' }
console.log(parseWithTemplate(template, input2));
// { artist: 'Taylor Swift', song: 'Anti-Hero', id: 'ID123]' }
console.log(parseWithTemplate(template, input3));
// { artist: 'Taylor Swift', song: 'Anti-Hero', id: 'ID123' }

方案优势

  • 自动处理静态文本的正则转义,避免手动转义的疏漏
  • 使用非贪婪匹配(.*?),支持匹配包含连字符、特殊符号在内的任意内容,解决原方案的字符范围限制问题
  • 精准分离令牌与静态文本,彻底避免替换冲突
  • 当模板中的静态标记(如ID的方括号)缺失时,会自动将缺失部分纳入令牌匹配内容,符合实际需求

内容的提问来源于stack exchange,提问作者Tristan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 16:00:53