JavaScript 中使用 Intl.Segmenter 进行国际文本分割

JavaScript 中使用 Intl.Segmenter 进行国际文本分割

了解 Intl.Segmenter 如何改进 JavaScript 中的文本分段以实现国际化

在 JavaScript 的广阔领域中,Intl对象在促进语言敏感的字符串比较、数字格式化以及日期和时间格式化方面发挥着关键作用。在其众多令人印象深刻的功能中,最引人注目的是Intl.Segmenter。这个强大的工具可以实现区域设置敏感的文本分段,从而更轻松地从字符串中提取有意义的项目,例如字素、单词或句子。

对国际分段器的需求

您可能想知道为什么我们有split()这个方法还需要Intl.Segmenter.为了理解这一点,让我们举一个简单的例子。假设我们想将一个字符串分解成句子。基本方法可能如下所示:

javascript 复制代码
'Hello there! How are you doing?'.split(/[.!?]/);

这段代码会给我们一个数组['Hello there', ' How are you doing', '']:虽然它似乎有效,但存在一些问题:

  1. 用作分隔符的标点符号现在消失了。
  2. 某些生成的字符串中有前导空格。
  3. 这种方法对语言不敏感。它对于不使用.!?来结束句子的语言效果不佳。

假设我们正在处理一个日语字符串:"吾辈は猫である。名前はたぬき。",它翻译为"我是一只猫。我的名字是狸猫。"我们的简单split()方法是不够的。这就是Intl.Segmenter起作用的地方!

国际分段器的原理

Intl.Segmenter允许我们将字符串分割成有意义的部分。我们只需要定义一个区域设置和粒度(可以是一个句子、单词或字素),它就可以分割任何字符串。

这是使用的示例Intl.Segmenter

ini 复制代码
const germanSegmenter = new Intl.Segmenter('de', {  
granularity: 'word'  
});  
const germanSegments = germanSegmenter.segment('Was geht ab, Freunde?');

在此片段中,我们将德语字符串分解为单词。

Segmenter.segment的返回

segment()方法不返回数组,而是返回一个可迭代对象。要访问所有段,我们可以使用数组扩展、Array.from()for...of循环。

您可以这样做:

ini 复制代码
const germanSegmenter = new Intl.Segmenter('de', {  
granularity: 'sentence'  
});  
const germanSegments = germanSegmenter.segment('Was geht ab, Freunde?');  
  
console.log([...germanSegments]);  
console.log(Array.from(germanSegments));  
for (let segment of germanSegments) {  
console.log(segment);  
}

每个段包括原始字符串值 ( input)、原始字符串中的字符索引 ( index) 和实际段字符串 ( segment)。

将段映射到其字符串值

如果要将段映射到其字符串值,可以使用 的第二个参数Array.from(),它是一个映射函数。

这是一个例子:

ini 复制代码
const germanSegmenter = new Intl.Segmenter('de', {  
granularity: 'sentence'  
});  
const germanSegments = germanSegmenter.segment('Was geht ab?');  
  
console.log(Array.from(germanSegments, s => s.segment));

使用 isWordLike 属性

将字符串拆分为单词时,所有段都包含空格和换行符。值得庆幸的是,Intl.Segmenter提供了一个isWordLike可以帮助过滤掉这些的属性。就是这样:

ini 复制代码
const germanSegmenter = new Intl.Segmenter('de', {  
granularity: 'word'  
});  
const germanSegments = germanSegmenter.segment('Was geht ab?');  
  
console.log([...germanSegments].filter(s => s.isWordLike));

在此示例中,我们过滤掉所有非单词的片段。因此,空格、标点符号和换行符将从结果中排除。

使用 Intl.Segmenter 处理表情符号

令人兴奋的应用之一Intl.Segmenter是它能够将字符串分割成视觉表情符号。表情符号可能非常复杂,尤其是随着由多个代码点组成的复合表情符号的出现。

让我们考虑一下这串表情符号:"🫣🫵👨‍👨‍👦‍👦"。

如果我们尝试按代码单元甚至代码点拆分它,我们将不会得到预期的结果:

ini 复制代码
const emojis = '🫣🫵👨‍👨‍👦‍👦';  
  
console.log(emojis.split('')); // Split by code units  
console.log([...emojis]); // Split by code points

然而,Intl.Segmenter优雅地处理这个问题:

ini 复制代码
const emojis = '🫣🫵👨‍👨‍👦‍👦';  
  
const segmenter = new Intl.Segmenter('en', {  
granularity: 'grapheme'  
});  
console.log(Array.from(segmenter.segment(emojis), s => s.segment));

在这种情况下,我们将每个复合表情符号作为单独的字素。

总结

随着 Web 应用程序的复杂性和全球化不断增长,像这样的工具Intl.Segmenter可能会改变游戏规则。它为 JavaScript 带来了语言感知的字符串处理,使得分段等任务不仅成为可能,而且相对简单。

相关推荐
白晨并不是很能熬夜2 分钟前
【PRC】第 2 篇:Netty 通信层 — NIO 模型 + 自定义协议 + 心跳
java·开发语言·后端·面试·rpc·php·nio
IT_陈寒36 分钟前
JavaScript里这个隐式类型转换的坑,我终于爬出来了
前端·人工智能·后端
方呵呵1 小时前
一个 3.5k Star Vue H5 项目的二次进化:我把它重构成了 Monorepo 工程体系
前端
_风满楼1 小时前
HTTP 请求的五种传参方式
前端·javascript·后端
木斯佳1 小时前
前端八股文面经大全:字节暑期前端一面(2026-04-22)·面经深度解析
前端
光影少年1 小时前
前端线上屏幕出现卡顿如何排查?
开发语言·前端·javascript·学习·前端框架·node.js
Yeh2020581 小时前
request与response笔记
java·前端·笔记
像我这样帅的人丶你还2 小时前
前端监控体系与实践:从错误上报到内存与 GC 观测
前端·javascript·架构
前端毕业班2 小时前
uni-app 小程序主包瘦身指南 - 分包 node_modules
前端
LinDaiDai_霖呆呆2 小时前
我用 Claude Code 一天搭了个高扩展性的 Web 3D 编辑器 SDK,但最有价值的不是代码 🔥
前端·ai编程·claude