@agulbra/uts58

中文文档
0.2.6发布于 2026/10/30BSD-2-ClauseTypeScriptES Module近 30 天下载 9640

UTS #58 为JavaScript所提取的网页链接.

中文使用文档
文档目录8 节
  1. 安装
  2. 使用量
  3. 电子邮件地址
  4. 选择公共后缀检查
  5. 建议的试验案例和显著行为
  6. 什么不在这里
  7. 重生成生成的表格
  8. 许可证

uts 58 号

JavaScript 执行 UTS58卫星, (中文(简体) ), 用于在运行中文本中查找链接的 Unicode spec 。 说来话长 返回其中的 URL 及其 UTF-16 偏移。 这是港口 页:1 鲁比 uts58 宝石;测试套房是 相同,但差别很小.

对相关操作系统进行了广泛测试: CI

安装

npm install @agulbra/uts58

仅限ESM;节点18+(使用Unicode属性逃脱并外观后方). 从0.2.4开始 浏览器也应该有用.

使用量

import { extractUrls, extractUrlsWithIndices } from '@agulbra/uts58';

extractUrlsWithIndices('see https://example.com/ for details');
// => [{ url: 'https://example.com/', indices: [4, 24] }]

extractUrls('see https://example.com/ for details');
// => ['https://example.com/']

API 镜像 twitter-text是因为 Extractor#extractUrlsWithIndices 密切; 写它是为了提供 马斯托顿式的消费者需要的 两者 上面的顶级函数也会通过 Extractor#removeOverlappingEntities: 候选人按开始排序 和任何开始于 早期幸存者的时间段 掉下来了 长度不包含在内;开始较早的候选人 即使后期的胜负更长.

导入 Extractor 如果你愿意和别人合并的话 提取器(注释、标签.)和解决所有重叠 他们自己.

承认没有计划的投入 https:// 预设于 已返回 url数字 :

extractUrlsWithIndices('blogspot.com is still a thing');
// => [{ url: 'https://blogspot.com', indices: [0, 12] }]

一样 twitter-text你可以通过 { extractUrlsWithoutProtocol: false } 只查找从 http:// 或者说 https://默认为 true与UTS58相匹配 .

IDN在输出中被解码为使用UTF-8,以便更好的可读性:

extractUrls('xn-----ctdbabcfhu9c2b9l1acccr4c.xn--mgbah1a3hjkrd')[0];
// => 'https://تجربة-القبول-الشامل.موريتانيا'

(诚然,如果不能读阿拉伯语,输出不易读取. 不过 无论他们能读哪种语言

跟踪出点、平衡括号、端口、路径、查询和 按规格处理碎片。 输出中的索引为 UTF-16 代码单位抵消( String.prototype.slice, (中文(简体) ), String#length,DOM,和文本编辑器),所以 text.slice(start, end) 返回直接匹配的子字符串,甚至跨字符 在BMP门外 (这与鲁比版本不同. 鲁比喜欢 用代码点抵消, Ruby 宝石跟着 公约. example.com/🐪/#camel 是一个很好的测试 区别, 因为emoji是一个代码点 但两个UTF-16单位

电子邮件地址

import {
  extractEmailAddresses,
  extractEmailAddressesWithIndices,
  extractEntities,
  extractEntitiesWithIndices,
} from '@agulbra/uts58';

extractEmailAddressesWithIndices('contact info@grå.org today');
// => [{ email: 'info@grå.org', url: 'mailto:info@grå.org', indices: [8, 20] }]

extractEmailAddresses('contact info@grå.org today');
// => ['info@grå.org']

每一个结果都带着光 email (单位:千美元) mailto: url,所以这个 直接掉入任何已经形成 url 实体。 这个 域名的IDN-解码方式与输入方式相同 extractUrls和领先 mailto: 在输入中吸收为 indices 每UTS58 5.2.

一个简单的地址与空域重叠 extractUrls 会发现 之后 @。 。 。 . extractEntitiesWithIndices 运行两个提取器, 排序并删除重叠。 电子邮件地址开始 并赢得它内部的域:

extractEntities('mail arnt@grå.org or see blogspot.com');
// => ['mailto:arnt@grå.org', 'https://blogspot.com']

选择公共后缀检查

决定是否 something.example 是一个可信的链接,提取器 对照一个公共后缀表检查主机. 哪张桌子是捆绑时间 选择 :

导入图表击出
@agulbra/uts58 (默认)公共后缀列表, ICANN 部分~5 KB 键
@agulbra/uts58/ianaIANA 根区 TLDs~5 KB 键
@agulbra/uts58/core没有,你提供支票0个KB

三个都暴露了同一个API. 两张桌子大小差不多 并且几乎同意每个东道主。 区别在于检查有多严格 是为少数只登记在第二位的TLD 级别. @agulbra/uts58/iana 仅问“最正确的标签是真实的 TLD":足以告诉 blogspot.jp 从 blogspot.exe 和拒绝 类似 example.cmo但它对待一个赤裸裸 foo.za 作为 难以置信。 默认 @agulbra/uts58 携带 PSL,它知道 南非登记 co.za 编号 : org.za 故你应当否认赤裸的 foo.za如果这种区别对你无关紧要的话,表格就是 可互换.

也没有复制 PSL 的通配符/例外规则: 这里的问题是 "这可能是一个链接" 不是"哪里是确切的可登记边界" 所以 统一会员制是它所做的一切。 PSL 表格相应折叠, 这就是为什么gzip表只比IANA列表大出几字节.

@agulbra/uts58/core 捆绑完全没有表格,然后插入自己的表格 像这样检查 :

import { Extractor } from '@agulbra/uts58/core';
import { parse } from 'tldts';

const ex = new Extractor({
  isPlausibleHost: (host) => {
    const p = parse(host);
    return !!p.domain && p.isIcann && p.publicSuffix !== 'invalid';
  },
});
ex.extractUrls('see example.com here');

这条路线也是你如何用PSL语义 来取回精确的PSL语义的 依赖您选择的不是这个包的力量 。 ()@agulbra/uts58 本身仅取决于 punycode. ) (中文(简体) )

建议的试验案例和显著行为

有一些尖锐的边缘 你也许应该覆盖 在自己的测试.

这个 href 而可见文本不是相同的字符串. 对于 see example.com here,则 indices 间距 example.com不过 url 时间更长 https://example.com。 。 。 . 使用 url 联 合 国 href 属性,将原始文本从 indices 对于可见的内容。 比较一下 text.slice(start, end) === url 所有无计划的投入都将失败, 和每个IDN上的A-标签被解码.

没有 autoLink。 。 。 . 这个包裹是提取的,它不渲染。 还有 无等值 twitter-text是因为 autoLink, (中文(简体) ), autoLinkUrlsCustom, (中文(简体) ), htmlEscape等——构建HTML是呼叫者的工作. 此代码 不决定逃跑.

没有提及,标签,现金,答复. UTS58没有定义 他们,所以这个包裹也没有。 如果你需要的话,快跑 twitter-text (或另作取出者) 合并到 Extractor#removeOverlappingEntities。 。 。 .

重叠解析为起步取胜,不是最长取胜. 这需要测试 当您从多个提取器合并实体时. ask [email protected]/02074960909 for details 说明为什么 生下来的 提取器查找两个邮件 [email protected] 时间 [4, 21] ưμ㼯a https://example.com/02074960909 时间 [10, 33]。初赢保持 [email protected]人类读者可能认为 至少一个读了02074960909的电话号码. 最长的赢会保持更长的时间 https://example.com/02074960909。 。 。 .

maxLength 测量匹配输入跨度. 不是返回的 URL . 如果您通过 12 个码口, 密码会保留 blogspot.com (12) 和 减 https://example.com,即使输入跨度和 url 刚好 那边一样 非对称性出现了相反的方式 example.com (11个输入cp,19英吋) url),其中12个上限允许代码 检测链接.

虽然大部分API都以UTF-16(如"弦")来计算 类, MaxLength 使用代码点。 原因是大多数API 用于软件开发,但最大Length是用于终端用户 代码点更接近终端用户所看到的。“qq”和“qq”都是其中之一 代码长。 (这还不算完美: "é"可能是其中之一或 2个代码长而"Q"为2个. 生平艰难. )

mailto: 被吸收为 indices。 。 。 . 每UTS58 5.2,输入 mailto:[email protected] 返回覆盖 整个23码点运行, 不只是地址。 这个 email 字段还原 保持赤裸的地址。 如果您的链接传输代码假设跨度 从本地部分开始, 邮件输入会给它带来惊喜 .

什么不在这里

  • 链接验证. 已识别的 URL 不被获取、 正常化 除了IDN解码, 或者他们的主机名在 DNS 中检查。 有一个 * 未试图检查可能的攻击Мышκин.рф 财务报告和审定财务报表 Мышкин.рф 注意希腊卡帕在中间 王子的名字).

重生成生成的表格

src/constants.js (链接终止和括号表) ruby 参考文献 constants.rb数字 :

npm run maketables

写着 ../ruby/lib/uts58/constants.rb 默认; 传递指向路径 在别的地方. constants.rb 本身在鲁比一侧产生,在那里 tools/maketables.rb 下载 UTS58 数据文件(LinkTerm.txt 财务报告和审定财务报表 LinkBracket.txt直接从unicode.org, 所以真理的来源是 Unicode发布数据.

src/tlds-iana.js 财务报告和审定财务报表 src/suffixes-psl.js 是公共后缀表格. 没有争吵,他们从他们的神话来源获得 (单位:千美元)冰岛, (中文(简体) ), PSL 软件) (中文(简体) ). 通过本地 线下再生路径 :

npm run maketlds
npm run maketlds -- /path/to/tlds-alpha-by-domain.txt /path/to/public_suffix_list.dat

许可证

BSD-2-克劳斯. 见 LICENSE。 。 。 .

FWIW,我写这个作为我在ICANN工作的一部分,并将保持为 同一作品的一部分。 (我解决了与Unicode有关的 域、电子邮件地址和类似地址,因此更多人,更多 以他们喜欢的方式使用互联网

版本与发布记录

@agulbra/uts58 共发布 4 个版本,首次发布于 2026/06/25;过去 12 个月发布了 4 个版本。

版本发布日期距今
0.2.6latest2026/10/309 天前
0.2.52026/10/2414 天前
0.2.42026/10/2018 天前
0.2.32026/06/254 个月前

关于 @agulbra/uts58 的常见问题

@agulbra/uts58 是什么?

UTS #58 为JavaScript所提取的网页链接.

如何安装 @agulbra/uts58?

在项目目录运行 npm install @agulbra/uts58,或使用 pnpm add / yarn add / bun add。

@agulbra/uts58 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@agulbra/uts58 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@agulbra/uts58 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=18。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@agulbra/uts58 可以商用吗?

@agulbra/uts58 使用 BSD-2-Clause 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@agulbra/uts58 的下载量有多少?

根据 npm 官方下载统计,@agulbra/uts58 在 2026/10/05 – 2026/11/03 这 30 天内被下载 9,640 次,日均约 321 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@agulbra/uts58 还在维护吗?

最新版本 0.2.6 发布于 2026/10/30(9 天前);至今共发布 4 个版本,其中过去 12 个月发布了 4 个;首次发布于 2026/06/25。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。