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

JavaScript:移除字符串标点但保留撇号并拆分单词的问题

解决单词提取时保留内部撇号的问题

你的核心问题是原来的正则会把单词内部的撇号(比如wasn't里的')当成无效字符删掉,因为\w只包含字母、数字和下划线,不包含撇号。我们可以换个思路,直接精准匹配符合要求的单词,而不是先做全局替换再分割。

推荐解决方案

直接使用match()方法匹配所有目标单词:单词可以是纯字母,或者字母+内部撇号+字母的组合(撇号不能在开头或结尾)。代码如下:

const sentence = "Exclamation! Question? \"Quotes.\" 'Apostrophe'. Wasn't. 'Couldn't'. \"Didn't\".";
const extractedWords = sentence.match(/\b[a-z]+(?:['’][a-z]+)?\b/gi).map(word => word.toLowerCase());

console.log(extractedWords);
// 输出: ["exclamation", "question", "quotes", "apostrophe", "wasn't", "couldn't", "didn't"]

正则规则解释

  • \b:单词边界,确保我们匹配的是完整单词,不会截取长单词的一部分
  • [a-z]+:匹配一个或多个字母(配合i标志忽略大小写,大写字母也能被识别)
  • (?:['’][a-z]+)?:非捕获组,匹配一个撇号(包括智能引号’)+ 一个或多个字母,?表示这个组是可选的——既可以匹配纯字母单词,也能兼容wasn't这类带内部撇号的单词
  • gi:全局匹配(g)+ 忽略大小写(i)

为什么原来的方法失效?

你原来的代码:

sentence.toLowerCase().replace(/[^\w\s]/gi, "").split(" ");

这里的[^\w\s]会匹配所有非单词字符(\w不包含撇号)和非空格的字符,所以wasn't里的'会被替换为空,最终变成wasnt,不符合预期。

另一种替换思路(可选)

如果你更习惯用replace+split的方式,也可以先去掉包裹单词的单双引号,再清理其他标点,同时保留单词内部的撇号:

const extractedWords = sentence.toLowerCase()
  // 移除包裹单词的单双引号
  .replace(/(^|\s)['"]([^'"]+)['"](\s|$)/g, '$1$2$3')
  // 清除除字母、空格、撇号外的所有字符
  .replace(/[^\w\s']/g, '')
  // 按一个或多个空格分割(避免多空格产生空字符串)
  .split(/\s+/)
  // 过滤可能存在的空字符串
  .filter(Boolean);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:01:17