许多文本工具简单到完全可以在浏览器中运行。

句子计数器就是一个很好的例子。浏览器已经具备接受文本、分析文本并显示有用统计信息所需的一切。将输入发送到远程服务器通常是不必要的。

我构建了一个小型的浏览器句子计数器,作为 TextFixHub 的一部分,这是一个免费的日常写作和编辑文本工具集合。

你可以在这里试用:

TextFixHub 句子计数器

为什么本地处理文本?

文本输入可能包含敏感信息。它可能包含:

  • 文章草稿
  • 学校作业
  • 内部笔记
  • 客户消息
  • 代码注释
  • 未发布的内容

对于一个基本的计数工具,将这些文本上传到服务器不会提供太多额外价值。本地处理有几个有用的特性:

  • 输入不需要离开用户设备。
  • 不需要维护文本处理 API。
  • 工具无需等待网络请求即可响应。
  • 应用程序无需用户账户即可工作。
  • 服务器不需要存储或处理提交的文本。

这并不意味着每个浏览器应用默认都是私密的。分析、第三方脚本、错误报告和托管配置仍然重要。这只是意味着核心文本分析可以保持本地化。

工具计算的内容

句子计数器显示的内容不仅仅是句子总数。它还计算:

  • 句子数
  • 字数
  • 带空格的字符数
  • 不带空格的字符数
  • 段落数
  • 行数
  • 平均句长
  • 平均词长
  • 预估阅读时间
  • 预估朗读时间

这些额外的统计信息使该工具对编辑和审阅内容更有用,而不仅仅是回答“有多少个句子?”

简单的分析流程

浏览器端流程设计得非常简单:

  1. 从文本输入读取当前值。
  2. 规范化相关空白。
  3. 检测句子边界。
  4. 将文本拆分为单词、段落和行。
  5. 计算衍生统计信息。
  6. 立即渲染结果。

重要的设计选择是输入在此过程中始终留在浏览器中。

简化的实现如下所示:

type TextStats = {
  sentences: number
  words: number
  characters: number
  charactersWithoutSpaces: number
  paragraphs: number
  lines: number
}

function countWords(text: string): number {
  const normalized = text.trim()

  if (!normalized) {
    return 0
  }

  return normalized.split(/\s+/).length
}

function countCharactersWithoutSpaces(text: string): number {
  return text.replace(/\s/g, '').length
}

Enter fullscreen mode Exit fullscreen mode

实际实现还需要处理空输入、仅空白输入、段落边界,以及可见字符与空白字符的区分。

句子边界并不完全简单

在出现真实文本之前,计数句子看似简单。

简单的方法可以统计 .!? 等标点符号。然而,句号也可能出现在:

  • 缩写
  • 小数
  • 域名
  • 电子邮件地址
  • 版本号
  • 首字母缩写

这意味着句子计数器不应暗示完美的语言理解。它是一个具有明确启发式的实用文本工具。

对于轻量级浏览器工具,透明的启发式方法通常比大型自然语言处理依赖更有用。该工具还应解释其统计内容,并避免将近似结果呈现为科学的语言学测量。

阅读时间和朗读时间

阅读和朗读时间是基于字数的估算。

例如,应用程序可以使用不同的每分钟字数假设:

const READING_WORDS_PER_MINUTE = 200
const SPEAKING_WORDS_PER_MINUTE = 130

const readingMinutes =
  wordCount / READING_WORDS_PER_MINUTE

const speakingMinutes =
  wordCount / SPEAKING_WORDS_PER_MINUTE

Enter fullscreen mode Exit fullscreen mode

这些数字并非适用于所有读者或朗读者的普遍事实。它们是简单的参考估算,帮助用户了解其文本的大致规模。

界面应避免暗示虚假的精确性。显示“约 2 分钟”通常比显示带有若干小数位的值更有用。

为什么我使用静态部署

该应用使用 Next.js 和 TypeScript 构建,并部署为静态网站。

该工具不需要数据库或应用服务器来分析文本。这使架构保持精简:

  • UI 在浏览器中运行。
  • 文本处理函数是常规的 TypeScript 模块。
  • 页面可以静态生成。
  • 部署范围小于基于服务器的实现。

更小的架构也使隐私解释更容易验证:主要文本操作在客户端应用中可见,而不是隐藏在 API 之后。

测试文本处理函数

UI 只是工具的一部分。文本处理函数应使用以下情况独立测试:

  • 空输入
  • 仅空白输入
  • 单个句子
  • 多个段落
  • 多个换行
  • 句末标点
  • 包含数字的文本
  • 包含 Unicode 字符的文本
  • 包含重复空格的文本

将计数逻辑与 UI 分离,使这些情况更容易测试,并减少视觉更改破坏底层计算的可能性。

我学到的东西

主要经验是,小型工具仍然需要明确的边界。

句子计数器不需要账户系统、数据库或文本处理 API。它需要:

  • 明确定义的计数方法
  • 超出单个数字的有用输出
  • 对空输入和异常输入的合理处理
  • 核心函数的测试
  • 对用户文本处理方式的清晰说明

本地优先处理并非对整个网站的完整隐私保障。它是针对核心任务的实用架构决策:输入到工具中的文本无需上传即可完成工作。

完成后的工具可在此处获取:

试用 TextFixHub 句子计数器

其他 TextFixHub 工具可在 https://www.textfixhub.com/ 获取。