You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何修改正则表达式,删除字符串重复单词时排除指定词汇?

解决删除重复单词但保留指定单词的问题

你的原正则表达式其实存在一些问题,比如它会匹配较长的连续字符(可能包含多个单词),而不是单个独立单词,而且没法直接实现"排除指定单词"的需求。下面给你两种解决方案,优先推荐更灵活的JavaScript回调函数方式:

方案一:使用回调函数(推荐,灵活易维护)

这种方式可以动态处理排除列表,还能保留原字符串的标点和空格格式,可读性也更强:

setFinal(final) {
  // 1. 定义需要排除的单词(这些单词重复也不会被删除,可根据需求修改)
  const excludedWords = new Set(['the', 'a', 'an', 'and']);
  const seenNonExcluded = new Set();
  
  // 2. 拆分字符串为「单词」和「分隔符(空格、标点等)」,保留原格式
  const words = final.match(/\b[\w'-]+\b/g) || []; // 匹配单词,支持连字符和撇号
  const separators = final.match(/[^\w'-]+/g) || []; // 匹配非单词部分
  
  const resultParts = [];
  let idx = 0;
  
  // 3. 遍历合并,处理重复逻辑
  while (idx < words.length) {
    const currentWord = words[idx];
    const lowerWord = currentWord.toLowerCase(); // 不区分大小写去重(不需要的话可删除)
    
    if (excludedWords.has(lowerWord)) {
      // 属于排除列表的单词,直接保留
      resultParts.push(currentWord);
    } else {
      // 非排除单词,只保留第一次出现的
      if (!seenNonExcluded.has(lowerWord)) {
        resultParts.push(currentWord);
        seenNonExcluded.add(lowerWord);
      }
    }
    
    // 添加上对应的分隔符(比如空格、逗号)
    if (idx < separators.length) {
      resultParts.push(separators[idx]);
    }
    
    idx++;
  }
  
  // 处理字符串末尾的分隔符(比如以标点结尾的情况)
  if (separators.length > words.length) {
    resultParts.push(separators.at(-1));
  }
  
  // 合并结果并去除首尾空格
  const res = resultParts.join('').trim();
  // ... 其他代码
  return res;
}

代码说明:

  • Set存储排除单词和已出现的非排除单词,保证查找效率
  • 拆分单词和分隔符是为了保留原字符串的格式(比如"hello, world hello"处理后会变成"hello, world",而不会破坏标点)
  • 支持不区分大小写去重(如果需要严格区分大小写,删掉toLowerCase()即可)

方案二:纯正则表达式(适合固定排除列表)

如果你的排除列表是固定不变的,可以用正则的否定前瞻来实现,但这种方式局限性较大(排除列表过长时正则会很臃肿,且无法动态修改):

setFinal(final) {
  // 把排除单词转成正则的否定前瞻,注意转义特殊字符
  const excluded = 'the|a|an|and';
  // 正则逻辑:匹配非排除的单词,且后面存在重复的该单词
  const regex = new RegExp(`\\b(?!(${excluded})\\b)(\\w+)\\b(?=.*\\b\\2\\b)`, 'gi');
  
  // 替换重复的非排除单词为空,然后去首尾空格
  let res = final.replace(regex, '').trim();
  // ... 其他代码
  return res;
}

注意事项:

  • 如果排除单词包含正则特殊字符(比如.*),需要先转义(可以用word.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')处理)
  • 这种方式只会删除前面的重复项,且可能因字符串中其他内容干扰出现匹配错误,不如方案一可靠

内容的提问来源于stack exchange,提问作者Matteo Pietro Peru

火山引擎 最新活动