「文字轉 slug」命令列與線上工具的比較,實際上歸結為三件事:程式碼在哪裡執行、套用哪些字元規則,以及標題是否會離開你的裝置。命令列 slug 工具是一段腳本或套件——Bash 單行指令、Python 模組、npm CLI 工具——你從終端機呼叫它並把文字串接進去。線上轉換器通常是一個帶有文字框和結果面板的網頁,常在瀏覽器中實作,因此工作是在頁面載入後才進行。兩者的輸出都應該是一個小寫、以分隔符連接的識別碼,適合用於 URL 路徑、檔名、錨點或 CMS 的 slug 欄位,但從原始標題到該識別碼的路徑很少相同。命令列工具經常內建一個轉寫字典,將帶有變音符號的字母、非拉丁文字和符號對應到近似的 ASCII 字元。線上瀏覽器工具則更常依賴 Unicode 本身的 NFKD 正規化,將字元折疊成基礎形式,然後依據明確的規則集篩選結果。因此同樣的輸入,最後得到的 slug 可能看起來相當不同,這就是為什麼在實際工作上挑選其中一方之前,先了解各方實際在做什麼會很有幫助。

Slug 應該是什麼樣子
Slug 是 URL 中用來識別資源的那一段——通常是在網域和任何路徑前綴之後、查詢字串之前的那部分。在 CMS 中,它常常由文章標題衍生而來;在靜態網站產生器中,它會成為檔名;在路由系統中,則扮演一個穩定的鍵值。各種工具呈現的格式是一致的:小寫字母、數字,以及單一分隔符字元,並移除開頭與結尾的分隔符。工具之間意見分歧的地方在於:對帶有變音符號的字元、非拉丁文字、來源文字中混合的分隔符,以及最大長度所採取的規則。同樣的英文標題可以乾淨地通過兩邊的處理;含有變音符號、標點符號或其他文字系統的標題則不行,而輸出正是兩種作法開始分歧的地方。
命令列 Slug 工具實際的運作方式
以終端機為基礎的 slug 工具,從簡短的 shell 管線到可安裝的套件都有。典型的 Bash 作法會把輸入轉成小寫,把任何非英數字的連續字元替換成連字號,然後修剪掉頭尾的連字號。tr、sed 和 iconv 工具可以完成大部分工作,對純 ASCII 標題而言,一行指令就足夠了。一旦出現變音符號或其他文字系統,同樣的作法就開始顯得薄弱:它不是留下雜散的位元組,就是依賴 iconv 從一種編碼轉寫到另一種編碼。
可安裝的套件則加入轉寫表。Python 的 python-slugify 引入 Unidecode 來把字元對應到拉丁字母的相似字。Rust 的 crate slug 提供一個用於轉寫的功能開關。npm CLI 工具 slug-gen-cli 則主打 Unicode 轉寫功能。這些字典使用人工策劃的對映表,將「São Paulo」轉成「sao-paulo」、將「北京」轉成「bei-jing」,而非依賴 Unicode 標準。這種對映帶有主觀判斷:德文的 sharp s 在某個套件裡會變成「ss」,在另一個套件裡則變成「s」,& 號、破折號和其他標點的情況也一樣。
這種主觀性對於可預期、人類可讀的 ASCII 來說是一項特性,但也意味著兩個套件可能對相同輸入產生不同結果,而且專案中固定的字典版本在升級時可能會改變 slug。一個今天執行 slugify 的建置流程,明年可能因為字典更新而產生不同組合的 URL,對於一個不應該讓 URL 漂移的已發佈網站而言,這是一項實質的差異。
線上轉換器做了哪些不同的事
以瀏覽器為基礎的 slug 工具通常不需要伺服器往返。頁面只載入一次,其餘由 JavaScript 處理,結果在同一台機器上呈現。採這種作法的工具會直接公開其規則:使用哪個分隔符、最大長度是多少、是否保留非拉丁的 Unicode 字母和數字。由於轉換是執行在瀏覽器所使用的同一個引擎中,規則可以仰賴標準化的 Unicode 行為,而不是維護者撰寫的字典。
第一步是 Unicode NFKD 正規化,這是 Unicode 標準中定義的程序,會把字元分解為基礎形式和一系列組合記號。JavaScript 的 String.prototype.normalize 方法直接實作了這項功能,而 Unicode 標準附錄 #15 則定義了四種形式及其背後的相容性分解規則。在 NFKD 中,「Crème brûlée」會分解成「Creme brulee」加上組合記號;接著工具會移除這些記號、把字母轉成小寫,再篩選到實際使用的字元集。
這條路徑讓契約保持明確:一個字母只有在平台的 Unicode 表格認定它是字母時才會存活,一個變音符號只有在它不會被分解成 ASCII 基礎形式時才會存活。這裡沒有特定語言的查表、沒有主觀的西里爾字母轉拉丁對映,也沒有中文的拼音轉寫。對於草稿 URL 或 CMS 的規劃文件來說,這通常已經足夠。但對於需要精準轉寫的精緻公開 URL 而言,CLI 套件的字典作法可以產生更貼近編輯意圖的結果。
在瀏覽器中本地產生 Slug
對於一次性、需要明確規則的轉換,瀏覽器工具是最快的路徑。Text To Slug 完全在瀏覽器中執行,把標題作為輸入,並產生預覽加上可下載的 TXT 結果。確切的工作流程如下:
- 在輸入欄位中輸入要轉換的標題或詞組。
- 選擇連字號或底線作為分隔符,將最大長度設定在 1 到 200 個 Unicode 碼位之間,並決定是否保留非拉丁的 Unicode 字母和數字。
- 產生 slug,並在預覽面板中讀取其確切字元與長度。
- 當數值看起來正確時,將結果下載為 UTF-8 TXT 檔。
編輯任何欄位都會清除舊的結果,且轉換過程不會聯繫網路服務,因此相同的輸入搭配相同的選項,在同一個瀏覽器引擎上永遠會產生相同的 slug。
命令列與線上工具一覽
這兩種作法以不同的工具鏈解決重疊的問題。下表整理出實務上的差異,但並不聲稱某一邊在所有情況下都比較好。
| 面向 | 命令列 slug 工具 | 線上瀏覽器工具 |
|---|---|---|
| 程式碼在哪裡執行 | 本地終端機,透過 npm、pip、apt 或 shell 函式 | 瀏覽器分頁,通常在頁面載入後於用戶端執行 |
| 轉寫字典 | 通常內建一個用於產生拉丁字母相似字的字典 | 通常沒有;改為仰賴 Unicode 屬性 |
| 非拉丁文字 | 當字典中存在對映時,對映到拉丁字母 | 在 Unicode 模式下保留,在 ASCII 模式下移除 |
| 設定 | 安裝、固定版本、加入 PATH | 開啟一個 URL,無需安裝 |
| 批次與腳本化使用 | 原生支援——可串接檔案、迴圈處理標題、整合 CI | 除非搭配自動化,否則需手動複製貼上 |
| 隱私 | 輸入永遠不會離開本地機器 | 取決於處理是否在本地進行;用戶端工具可以完全私有 |
| 相同輸入的確定性 | 取決於固定的套件與字典版本 | 取決於瀏覽器的 Unicode 表格,變動緩慢 |
限制、截斷與邊界情況
承諾產生乾淨輸出的 slug 產生器仍然必須處理長尾情況。最常見的限制是長度、格式錯誤的輸入,以及分隔符與被移除字元之間的邊界。上述以瀏覽器為基礎的工具將最終值上限設為 200 個 Unicode 碼位,並拒絕超過 100,000 個 UTF-16 碼單位的輸入。截斷會在完整轉換之後執行,因此最後一個字元絕不會是 UTF-16 代理對的前半截,而由截斷產生的尾端分隔符會被移除,不會讓 slug 以分隔符作結。
空結果會以明確的錯誤訊息拒絕,而不是回傳空字串,這能防止某個設定把標題中的所有字元都移除掉。輸入中的孤立代理項也會在正規化之前被拒絕,因此預覽和 UTF-8 下載檔不會因為替代字元而悄悄地不一致。該工具刻意不嘗試在截斷落在某個單字內部時保留最後一個單字:這樣做不是超出所宣告的上限,就是遠低於該上限。兩個不同的標題在正規化後仍可能發生衝突,而目的端的 CMS、路由器或檔案系統應該強制執行唯一性,或附加其自身的穩定識別碼。
挑選適合工作的路徑
當 slug 是建置流程的一部分時,CLI 那一側勝出:靜態網站產生器把 Markdown 變成檔案、部署流程產生永久連結,或是腳本重新命名數千個檔案。安裝是一次性成本,且同一個指令在 CI、cron 工作和開發人員的筆電上執行會得到相同的結果。當特定的轉寫屬於編輯風格指南的一部分時,CLI 也同樣勝出,因為字典可以調整以符合該風格。
當作臨時性的工作時,線上那一側勝出:CMS 草稿、單一檔名、測試錨點,或類似類別名稱的識別碼。無需安裝、不用固定版本,且規則都直接顯示在控制項中。用戶端實作也能讓標題留在裝置上,這對尚未發佈的內容來說很重要。若需要更複雜的瀏覽器工作流程,包括深入了解瀏覽器工具如何取代 API 呼叫,Text to Slug API alternative 一文會介紹如何在沒有伺服器往返的情況下完成相同的轉換。
對大多數日常情況而言,在瀏覽器中本地執行轉換是最輕鬆的路徑:規則明確、無網路呼叫、不需要維護字典,且結果可以儲存為純 UTF-8 文字檔。一旦工作需要重複、自動化或串接進建置流程,命令列路徑就展現其價值;只要底層規則與目的系統相符,兩條路徑都能產生完全有效的 slug。