# string.wordBreaker

统一的 Windows 分词入口：Windows 10 及以后直接使用 `string.wordsSegmenter`；旧系统使用注册的 COM `IWordBreaker`。无需自行编译 C++。

## 快速使用

```aardio
import string.wordBreaker;

// 与 string.wordsSegmenter 一样：先指定语言，后处理文本。
var breaker,err = string.wordBreaker("zh-CN"); // 可省略语言或传 null
if(!breaker){ print(err); return; }

var words,err = breaker.getWords("我爱北京天安门。hello world!");
if(words === null){ print(err); return; }
print(string.join(words," / "));
```

本机输出：`我 / 爱 / 北京 / 天安门 / hello / world`。

`string.wordBreaker.create(language)` 与 `string.wordBreaker(language)` 等价。指定其他语言：

```aardio
var english,err = string.wordBreaker("en-US");
if(english) print(english.getWords("hello world!"));

var japanese,err = string.wordBreaker("ja-JP");
if(japanese) print(japanese.getWords("日本語の文章を分割します。"));
```

分词器还提供 `getTokens(text)`、`getTokenAt(text,startIndex)`、`language` 和 `resolvedLanguage`。`getTokenAt` 的索引、词的位置和长度使用从 0 开始的 UTF-16 单位；旧系统不提供替代词形，`alternateForms` 总是 `[]`。

## 兼容旧调用

原来的具名方法仍可用：

```aardio
var words,err = string.wordBreaker.breakText("我爱北京天安门。", "zh-CN");
```

**直接调用 `string.wordBreaker(...)` 的含义已改变**：现在参数是语言，返回分词器对象，不再把文本作为参数并直接返回词数组。旧代码请改为 `string.wordBreaker().getWords(text)`，或者使用上述 `breakText(text,language)`。

## 系统差异

- Windows 10 及以后：委托 `string.wordsSegmenter`，语言参数遵循其 BCP-47 规则；具体返回行为见该库文档。
- 较旧 Windows：使用系统 `ContentIndex\Language` 注册的 `WBreakerClass`。支持已安装的 `zh-CN`、`zh-Hans-CN`、`en-US`、`en-GB`、`ja-JP`、`und` 等语言别名，也可传入原始注册表语言名称；未安装或创建失败会返回 `null,err`，不会静默换用其他语言。
- 默认语言 `zh-CN`；`text` 为 `null` 时视作空文本，`getWords`、`getTokens` 返回 `[]`。不额外补回标点、空白，不保证词列表能拼回原文。
- 旧系统的 `getWords` / `getTokens` 每次独立创建、释放 COM 分词器；`create` 只检查注册信息，组件加载错误可能在分词时返回。旧系统路径仅在 Windows 10 上强制执行并测试了 COM 分支，未在较旧 Windows 系统上实际运行。

旧版 COM 实现参考 `XLWordBreaker.cpp` 的 `TEXT_SOURCE`、`IWordSink` 和结束回调。
