如何简便提取字符串中的所有有效单词?现有正则方案存在标点连带、缩写误拆分问题
从英文字符串中可靠提取单词的简便方案
你之前试的两种实现,问题本质都是对“什么是单词、单词的边界在哪”的定义太粗糙,完全不需要引入第三方分词库,只要调整正则的匹配规则,就能做出覆盖示例场景的可靠效果。
现有两种方案的踩坑原因
- 用
/\S+/g匹配连续非空白块的规则太松:只要标点和单词之间没有空格隔开,就会被当成单词的一部分。比如示例里的go,,按照这个规则会把带逗号的完整字符串当成一个“单词”,根本不符合预期。 - 用
\w规则的正则又太严:\w只认字母、数字、下划线,撇号根本不在它的匹配范围内,碰到don't这类带缩写撇号的词,直接就在撇号的位置断成don和t两个匹配项,完全不符合日常对单词的认知。
适配日常英文场景的简便实现
其实只要匹配的时候把英语单词的两个常见特征考虑进去就行:单词以连续字母为主体,中间可以夹杂缩写场景下的合法撇号,碰到空格、逗号、句号这类非字母字符就立刻停止匹配,不要把粘在单词前后的标点算进来。
对应的正则表达式写法很简单:/[a-zA-Z]+(?:'[a-zA-Z]+)*/g
实际运行效果
const testStr = "I don't want to go, mom" const words = testStr.match(/[a-zA-Z]+(?:'[a-zA-Z]+)*/g) console.log(words) // 最终输出:[ 'I', "don't", 'want', 'to', 'go', 'mom' ]
刚好和要求的正确返回结果完全一致。
如果碰到带连字符的复合词(比如well-known、mother-in-law),只要稍微调整下正则,把连字符也纳入合法的中间连接符范围就行:/[a-zA-Z]+(?:['-][a-zA-Z]+)*/g
调整之后,连字符连接的完整单词就不会被拆成零散的片段了。
这个方案的靠谱程度
- 写法足够简单,没有任何额外依赖,对绝大多数日常英文文本的单词提取需求都够用,比之前找的两个方案要可靠得多。
- 它不是万能的:如果是要处理多语言混杂、带特殊符号的高精度分词场景,正则的能力确实有上限,但这类场景本来就不属于“找简便实现”的需求范围。
内容的提问来源于stack exchange,提问作者user737163
相关产品推荐
相关产品推荐

