前端文本分割工具,“他”来了
大家好,我是CC,在这里欢迎大家的到来~
简介
在日常开发场景中大多数是使用空字符串、空格或者换行符来进行文本分割。现在可以试试新的分割工具-Intl.Segmenter。
Intl.Segmenter 支持根据语言进行的文本分割,将一个字符串分割成片段,分割类型包括字、词和句。
试试分割效果
以简体中文为例,这里我们先设置按照词(word)分割:
按词分割-多语言分词
const segmenter = new Intl.Segmenter("zh-Hans-CN", { granularity: "word" });
const string = "前端文本分割工具,“他”来了";
const iterator = segmenter.segment(string)[Symbol.iterator]();
for(let item of iterator) {
console.log(item.segment);
}
// 前端
// 文本
// 分割
// 工具
// ,
// “
// 他
// ”
// 来
// 了
效果还不错,有点类似词义分割了。再看看其他分割方式。
按字分割(默认)-处理复杂字符
在简体中文场景下效果与'前端文本分割工具,“他”来了'.split("")相同。
const segmenter = new Intl.Segmenter("zh-Hans-CN", { granularity: "grapheme" });
const string = "前端文本分割工具,“他”来了";
const iterator = segmenter.segment(string)[Symbol.iterator]();
for(let item of iterator) {
console.log(item.segment);
}
// 前
// 端
// 文
// 本
// 分
// 割
// 工
// 具
// ,
// “
// 他
// ”
// 来
// 了
按句分割-多语言句子分析
加了分号、感叹号、问号、句号这些标点符号,还是可以完整分割出来的。
const segmenter = new Intl.Segmenter("zh-Hans-CN", { granularity: "sentence" });
const string = "前端文本分割工具,“他”来了,前端文本分割工具,“他”来了;前端文本分割工具,“他”来了。前端文本分割工具,“他”来了,前端文本分割工具,“他”来了;前端文本分割工具,“他”来了!前端文本分割工具,“他”来了,前端文本分割工具,“他”来了;前端文本分割工具,“他”来了?";
const iterator = segmenter.segment(string)[Symbol.iterator]();
for(let item of iterator) {
console.log(item.segment);
}
// 前端文本分割工具,“他”来了,前端文本分割工具,“他”来了;前端文本分割工具,“他”来了。
// 前端文本分割工具,“他”来了,前端文本分割工具,“他”来了;前端文本分割工具,“他”来了!
// 前端文本分割工具,“他”来了,前端文本分割工具,“他”来了;前端文本分割工具,“他”来了?
完整数据格式
实际上分割出来的每个单位都是一个 JSON 对象,除了 segment 代表文本内容外,还有 index 代表索引、input 表示原文本完整内容、isWordLike 表示是否像文本单词(如果是标点符号类型的就会是 false)。
{
"segment": "前端",
"index": 0,
"input": "前端文本分割工具,“他”来了",
"isWordLike": true
}
分割的参数
locales
当然除了简体中文,Intl.Segmenter 也支持其他语言。
Intl.Segmenter 的第一个参数 locales 支持填写带有 BCP 47 语言区域标记的一个字符串,或者一个这样的字符串数组。
在 BCP 47 中表示语言、脚本、国家(区域)和变体(少用)的语言子标记含义可以在IANA 语言子标记注册 中找到。
localeMatcher
Intl.Segmenter 的第二个参数中除了可以选择如何分割外,还可以根据 ****locales ****在 ****lookup ****和 ****best fit ****之间选择一个匹配算法来配置 localeMatcher 参数。
best fit
默认值,运行时可能会选择一个可能比查找算法的结果更加合适的语言区域。
lookup
使用 BCP47 查找算法从 locales 参数中选择语言区域。像如果运行时支持 "de" 但不支持 "de-CH",用户传入的 "de-CH" 可能就会以 "de" 为结果进行使用。
分割对象的方法
分割字符串
上文中对分割文本对象进行分割的 segment 方法。
判断返回支持的 locale
在给定的 locales 数组中判断出 Segmenter支持的 locales。但是可能每个浏览器支持的不大一样。
const locales = ["ban", "id-u-co-pinyin", "de-ID"];
const options = { localeMatcher: "lookup" };
console.log(Intl.Segmenter.supportedLocalesOf(locales, options));
// ["id-u-co-pinyin", "de-ID"]
获取分割对象的配置参数
const spanishSegmenter = new Intl.Segmenter("es", { granularity: "sentence" });
const options = spanishSegmenter.resolvedOptions();
console.log(options.locale); // "es"
console.log(options.granularity); // "sentence"
在参数不支持的情况下会取当前运行环境中默认语言环境。
const banSegmenter = new Intl.Segmenter("ban");
const options = banSegmenter.resolvedOptions();
console.log(options.locale); // "zh-CN"
console.log(options.granularity); // "grapheme"
总结
Intl.Segmenter 很适合在文本处理场景下使用,给了一定的分割标准。它在文本编辑器中计算光标索引、搜索建议的生成、文本计算长度和文本过滤,甚至在自然语言处理场景中都可以使用到。
目前在 fabric.js 中也在考虑使用 Intl.Segmenter 来优化文本分割,可以研究学习。
大家可能也注意到了,Segmenter 只是 Intl 下的一个对象,还有针对像数字、复数、日期、地区等国际转化,这些后续去研究。