許多文字工具簡單到可以在瀏覽器中完全執行。

句子計數器就是一個很好的例子。瀏覽器已經具備接受文字、分析文字以及顯示實用統計數據所需的一切功能。將輸入傳送至遠端伺服器通常是不必要的。

我建立了一個小型的瀏覽器句子計數器,作為 TextFixHub 的一部分,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/ 取得。