你手里有一段文本,却没有可靠信息说明它属于哪种语言——可能是用户刚输入的一条评论、上传文件里的一段字符串,或一封新进支持工单的正文。在你把它路由出去、翻译它,甚至只是正确渲染它之前,首先需要知道它的 locale:是什么语言、对应哪个地区、使用哪种书写系统、阅读方向是什么。Recognize 一次调用就能补上这块空白。你发送文本,它返回一个结构化的 locale 身份信息,精确到文本本身所能支持的程度。
这一页会完整介绍这个端点——包括请求、响应及返回的每个字段、各语言绑定,以及当文本无法明确地区或书写系统时,响应会如何处理。这是一个同步调用:你通过 POST 提交文本,请求会在分析期间阻塞,并在同一次往返中返回结果。认证通过共享的 X-API-Key 请求头完成——密钥的工作方式请参见 Authentication——任何错误都遵循 标准错误模型。
请求#
POST /process/recognize| 参数 | 类型 | 说明 |
|---|---|---|
text | string | 要分析的文本 |
labelLocale | string(可选) | 用于可读标签的 locale(默认:en) |
只需提供 text。labelLocale 控制响应中可读 label 的显示语言——把它设为 de,法语输入返回的标签就会显示为德语,而不是英语。它不会改变识别结果,只会改变结果返回给你时的命名方式。
{
"text": "Bonjour le monde",
"labelLocale": "en"
}响应#
{
"locale": "fr",
"language": "fr",
"region": null,
"script": null,
"label": "French",
"direction": "ltr"
}| 字段 | 类型 | 说明 |
|---|---|---|
locale | string | 在当前可确认范围内最具体的 BCP-47 locale 代码 |
language | string | ISO 639 语言子标签 |
region | string | null | ISO 3166 地区子标签;若无法区分,则为 null |
script | string | null | ISO 15924 书写系统子标签;若为该语言的默认书写系统,则为 null |
label | string | 按请求的 labelLocale 返回的可读 locale 名称 |
direction | "ltr" | "rtl" | 文本方向 |
这个返回结构里有两点尤其值得仔细看,因为它们决定了结果不只是“有信息”,而是真正“能拿来用”。
第一,这些代码全部来自公开标准,而不是 Lingo.dev 自定义的一套体系。locale 是 BCP-47;language 是 ISO 639 子标签;region 是 ISO 3166;script 是 ISO 15924。所以无论你现在用什么解析 locale——你的 i18n 库、一次 Intl 调用,还是 CLDR 查询——都可以直接消费这份输出。你无需适配任何专有编码体系;拿到的就是你现有技术栈本来就在使用的那套标识符。
第二,region 和 script 被设计成可为空,而且这是刻意为之。只有当文本本身确实提供了足够证据时,它们才会返回具体值——接下来的两节会详细说明这一点,而这也正是这个端点避免“瞎猜”的关键。
只有当文本本身体现出地区和书写系统时,才会返回它们#
提到语言识别,最常见的担忧就是它会“过度判断”:明明一段文本并没有证明自己属于某个地区或书写系统,系统却硬给它贴上标签,而你再基于这个猜测去写业务逻辑。Recognize 恰好相反。只有在证据充分时,它才返回对应的子标签;否则就返回 null。
当文本里出现了地区线索——比如巴西葡萄牙语特有的用词——响应就会包含完整标签(pt-BR)。而当地区变体无法区分时,则只返回语言子标签(pt):
{
"locale": "pt-BR",
"language": "pt",
"region": "BR",
"script": null,
"label": "Portuguese (Brazil)",
"direction": "ltr"
}{
"locale": "pt",
"language": "pt",
"region": null,
"script": null,
"label": "Portuguese",
"direction": "ltr"
}同一种语言,两种都诚实的答案。第一段文本携带了足够的信息来确定地区;第二段没有,所以 region 会是 null,而 locale 也会收敛为 pt。script 也遵循同样的规则,只是从另一个维度体现:当书写系统是该语言的默认值时——比如法语默认使用拉丁字母——它会是 null;只有当书写系统本身构成区分依据时,才会明确返回。
null 不是缺失,而是信息
region: null 并不意味着识别失败。它的意思是:这段文本没有提供足够信息来区分地区,因此端点选择不凭空编造一个——此时 locale 只包含语言子标签。正确的理解方式是“精确到文本所允许的程度”:基于 locale 做分支,让 null 把你路由到语言级默认值,而不是把它当成错误。
这也是为什么你应该围绕 locale 来构建逻辑。它始终是文本所能支持的最具体标签——有证据时是 pt-BR,没有证据时是 pt——因此直接读取 locale,就能自动得到正确的粒度。你不需要再把各个部分重新拼装,也不用去怀疑一个看起来很确定、其实只是猜出来的地区标签。
有了 direction,你就能先渲染,再翻译#
语言识别很少是最终目的——大多数时候,你识别语言是为了对文本做点什么,而第一步通常就是先把它展示出来。响应里包含 direction,正是为此而设:它会告诉你文本是从左到右还是从右到左,这样你就能在进入翻译流程之前先设置 dir="rtl"、选择布局,或挑选合适的字体。阿拉伯语文本会返回 "rtl";上面的法语示例则会返回 "ltr"。你不必自己维护一张“语言到方向”的映射表——负责识别语言的端点,也会顺手把你最先需要的渲染信息一并交给你。
示例#
一次 POST,请求里带上文本和可选的 labelLocale 即可。响应就是上面那个结构化的 locale 对象。
const response = await fetch(
"https://api.lingo.dev/process/recognize",
{
method: "POST",
headers: {
"X-API-Key": "your_api_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
text: "Bonjour le monde",
labelLocale: "en",
}),
}
);
const result = await response.json();
// { locale: "fr", language: "fr", label: "French", direction: "ltr", ... }后续步骤#
识别语言,通常是为了基于结果采取下一步动作——最常见的就是翻译。Recognize 先告诉你源 locale,后面的本地化端点再接手完成后续流程。
