JS Intl.Segmenter 介绍

你想详细了解 JavaScript 中的 Intl.Segmenter 对象,它是 ES2022 引入的国际化 API,核心作用是按照不同语言的书写规则对文本进行精准分段(比如按字符、单词、句子拆分)。

一、核心概念与用途

Intl.Segmenter 是浏览器和 Node.js 提供的内置对象,用于语言感知的文本分段

  • 传统的 String.prototype.split() 是无语言感知的(比如对中文、日语等无空格分隔的语言拆分单词完全无效)。
  • Intl.Segmenter 会根据指定的语言规则(如中文按字、英语按单词/句子)拆分文本,解决了多语言文本处理的痛点。
  • 常见用途:文本高亮、字数统计、文本编辑时的光标定位、多语言文本分析等。

二、基本语法与参数

1. 构造函数

new Intl.Segmenter(locales, options);
  
  • locales:字符串或字符串数组,指定语言标签(如 'zh-CN' 中文、'en-US' 英语、'ja-JP' 日语),可选,默认使用运行时的默认语言。
  • options:配置对象,可选,核心属性:
    属性取值说明
    granularity'grapheme'(默认)字素拆分(视觉上的单个字符,如 emoji、合字)
    'word'单词拆分
    'sentence'句子拆分

2. 核心方法

  • segment(text):接收要分段的文本,返回一个可迭代对象(可通过 for...of 遍历),每个迭代项是包含分段信息的对象。

三、完整使用示例

下面通过不同场景的示例,带你理解 Intl.Segmenter 的用法:

示例 1:按字素(grapheme)拆分(默认)

适合处理多语言字符、emoji、合字(如中文、日语、带声调的拼音):

// 初始化 Segmenter,指定中文规则
const segmenterZh = new Intl.Segmenter('zh-CN', { granularity: 'grapheme' });
const textZh = '你好👋,JavaScript!';

// 遍历分段结果
for (const segment of segmenterZh.segment(textZh)) {
  console.log({
    分段内容: segment.segment,
    起始索引: segment.index,
    长度: segment.length,
    是否为单词边界: segment.isWordLike // 仅 word 粒度有效
  });
}

/* 输出结果(关键部分):
{ 分段内容: '你', 起始索引: 0, 长度: 1 }
{ 分段内容: '好', 起始索引: 1, 长度: 1 }
{ 分段内容: '👋', 起始索引: 2, 长度: 2 } // emoji 占 2 个字符位
{ 分段内容: ',', 起始索引: 4, 长度: 1 }
{ 分段内容: 'J', 起始索引: 5, 长度: 1 }
...
*/
  

示例 2:按单词(word)拆分(多语言适配)

// 英语单词拆分
const segmenterEn = new Intl.Segmenter('en-US', { granularity: 'word' });
const textEn = 'Hello world! This is JavaScript.';
const enWords = [...segmenterEn.segment(textEn)].filter(s => s.isWordLike);
console.log('英语单词列表:', enWords.map(s => s.segment));
// 输出:["Hello", "world", "This", "is", "JavaScript"]

// 日语单词拆分(无空格分隔)
const segmenterJa = new Intl.Segmenter('ja-JP', { granularity: 'word' });
const textJa = 'こんにちは世界';
const jaWords = [...segmenterJa.segment(textJa)].filter(s => s.isWordLike);
console.log('日语单词列表:', jaWords.map(s => s.segment));
// 输出:["こんにちは", "世界"]
  

示例 3:按句子(sentence)拆分

const segmenter = new Intl.Segmenter('zh-CN', { granularity: 'sentence' });
const text = '你好!今天天气不错。JavaScript 很有趣。';
const sentences = [...segmenter.segment(text)].map(s => s.segment);
console.log('句子列表:', sentences);
// 输出:["你好!", "今天天气不错。", "JavaScript 很有趣。"]
  

四、兼容性与注意事项

  1. 兼容性
    • 浏览器:Chrome 87+、Firefox 85+、Safari 14.1+ 支持。
    • Node.js:16.0.0+ 支持(需启用完整 ICU,默认已启用)。
    • 如需兼容旧环境,可使用 polyfill(如 @formatjs/intl-segmenter)。
  2. 关键注意点
    • isWordLike 仅在 granularity: 'word' 时有效,用于过滤标点/空格等非单词片段。
    • 字素(grapheme)是“视觉上的单个字符”,比如 é(合字)、👨‍👩‍👧(家庭 emoji)会被识别为一个分段,而传统 split('') 会拆分。
    • 不同语言的分段规则由 ICU(国际化组件)提供,结果符合该语言的书写习惯。

总结

  1. Intl.Segmenter 是 JS 中处理多语言文本分段的核心 API,解决了 split() 无语言感知的问题。
  2. 核心配置是 locales(语言)和 granularity(分段粒度:字素/单词/句子)。
  3. 核心用法是通过 segment() 方法获取可迭代的分段结果,遍历后可提取分段内容、位置等信息。

关键点回顾

  • 核心价值:语言感知的文本拆分,适配中文、日语等无空格分隔的语言。
  • 核心粒度:grapheme(字素,默认)、word(单词)、sentence(句子)。
  • 核心用法:实例化 Intl.Segmenter → 调用 segment(text) → 遍历/解构结果。