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
相关产品推荐
相关产品推荐

