在線上移除文字中的腔調符號(變音符號),意味著將 é、ñ、ü、ø、ł、đ 等字母轉換為其對應的純字母形式——café 變成 cafe、Zürich 變成 Zurich、Łódź 變成 Lodz——這樣結果就能用在 URL、檔案名稱、僅限 ASCII 的資料庫以及聯絡人清單中。多數人採取的快速做法是一段單行程式碼,它會將字串正規化並去除組合標記,但這種方式會悄悄地漏掉一整類字母(ø、ł、đ、ħ、þ 以及連字 æ、œ、ß),因為 Unicode 並未為它們記錄任何分解對應,因此什麼也不會被去掉,該字元原封不動地通過。當瀏覽器型的工具把那種方法與一張明確的折合表搭配使用——而且在過程中拒絕碰觸希臘文、西里爾文、CJK 或表情符號——才是搜尋「remove accents from text online」真正想要的。Remove Accents from Text 正是這麼做的:它會從拉丁字母基底中去除真正的變音符號,透過一張對照 Unicode 字元資料庫 驗證過的折合表來處理那些無法分解的字母,並回報實際被變更的字元數量。

remove accents from text online
在線上移除文字變音符號而不遺漏字母

為何正規化後去除的腳本會悄悄失效

幾乎每個快速線上腳本都會採用的方法只有兩行。你對輸入呼叫 String.prototype.normalize("NFD"),然後刪除所有類別以「M」開頭的 Unicode 字元——也就是組合標記。對大多數帶腔調的拉丁文來說這確實有效:é 會被拆成 e 加上組合銳音符,銳音符被刪掉,輸出就是純粹的 e。Unicode 協會在 UAX #15 中記載了這個行為,該報告定義了 NFD、NFC、NFKD、NFKC 等正規化形式,而 JavaScript 引擎 完全依規格實作。到此為止一切順利。

當輸入含有「腔調」其實不是獨立標記的字母時,問題就出現了。Unicode 並未為 ø、Ø、đ、Đ、ł、Ł、ħ、Ħ、ŧ、Ŧ、ı、ð、Ð 等字母記錄分解對應,這表示 NFD 會把它們保留為單一碼點,你的刪除迴圈也就無字可刪。Łódź 進去是 Łódź,出來還是 Łódź。相同的問題也發生在北歐與拉丁連字上:æ、œ、ß、þ 以及它們的大寫形式都是 Unicode 分解為空值的單一碼點,因此它們會原封不動地通過任何天真的處理流程。

這不是 NFD 的錯;它正是標準所描述的行為。但這也意味著,面對波蘭城市名、丹麥姓氏或德國街道名時,那常見的單行程式碼會悄悄地出錯。Remove Accents from Text 工具透過為這些字母維護一張明確的折合表來補上這個缺口,每個條目都對照 Unicode 字元資料庫檢查,因此同樣的波蘭文、丹麥文或德文內容在第一輪就會變成 Lodz、Odense 與 Strasse,而不是在正規化後原封不動。

如何在線上移除文字中的腔調

  1. 貼上文字,將含有腔調或特殊拉丁字元的內容貼入輸入框。單次最多可處理一百萬個字元,因此聯絡人清單、CSV 匯出或長篇文稿本文都能直接處理,無需切割或分批。
  2. 選擇邊角情況的處理方式。一個開關控制連字以及需要展開為字母組合的字母(æ 轉 ae、œ 轉 oe、ß 轉 ss、þ 轉 th,以及它們的大寫)。因為資料清理幾乎總是想要這些折合,所以預設為開啟;當你需要保留原始字母、卻仍然要去除真正的變音符號時,可以將它關閉。第二個開關控制是否要保留非拉丁腳本(這是預設),或是當你真的需要僅限 ASCII 的輸出時,全部去除。
  3. 點擊 Remove accents 並留意變更計數器。頁面會精確回報有多少字元被修改,這讓你能確認輸入確實被處理過,並大致掌握修改發生在哪裡。清理後的結果就在輸出框中一鍵可取,可立即複製到短網址、資料庫或程式碼檔案中。

此操作具有等冪性,這表示把清理後的輸出再丟回工具處理,結果不會再改變。預組成的輸入(é 視為單一碼點)以及分解後的輸入(e 後接組合銳音符)會產生相同的最終字串,因為實作會先套用 NFD、僅從拉丁字母基底上移除組合標記、執行折合表,然後在回傳結果前重新組合成 NFC。

哪些會被改、哪些保持原樣

下表展示一些常見輸入在三種不同策略下的表現:天真版的「正規化並去除」腳本、兩個開關都採預設值的 Remove Accents from Text 工具,以及同一個工具關閉音譯開關後的情況。

輸入僅用天真的 NFDRemove Accents from Text(預設)關閉音譯
cafécafecafecafe
ZürichZurichZurichZurich
ŁódźŁódź (無變更)LodzLodz
naïvenaivenaivenaive
señorsenorsenorsenor
straßestraße (無變更)strassestraße
ÆsopÆsop (無變更)AesopÆsop
Άλφα (希臘文)Αλφα (已損壞)Άλφα (未變動)Άλφα (未變動)
Привет (西里爾文)Привет (已損壞)Привет (未變動)Привет (未變動)

音譯開關是刻意拆出來的。把 ß 轉成 ss、þ 轉成 th、æ 轉成 ae 或 œ 轉成 oe,這跟移除腔調並不相同;那是把一個字母展開成兩個字母。工具把這類操作標記為音譯,並用獨立的開關來管理,而不是悄悄地把兩種操作混為一談——這在需要往返轉換文字或保留作者原有拼法時非常重要。兩個開關的預設行為都符合資料清理管線的期待,但每一步在同個畫面上都可見且可逆。

去除腔調真正派上用場的地方

人們搜尋「remove accents from text online」最常見的原因是為了產生短網址。URL、檔案名稱、部落格文章識別碼以及 Git 分支名稱都需要可預期的 ASCII,而 café-recipes.md 裡只要一個漏網的 é,就可能在設定不良的伺服器上導致下載失敗,或以不利於 SEO 排名的方式被百分比編碼。先把標題丟進這個工具,就能立刻把那個路徑變成 cafe-recipes.md,完全不必寫正則表達式。

第二大效益是聯絡人資料去重。同一個人在 CRM 中有兩筆紀錄——「Łukasz Kowalski」與「Lukasz Kowalski」,或「Stéphanie Müller」與「Stephanie Muller」——在精確比對的合併中會被當成不同紀錄。兩邊都跑過折合工具後,這些紀錄就會合併為一筆。同樣的邏輯也適用於系統遷移時的姓名比對、建構跨編碼必須保持穩定的識別碼,以及為不懂 UTF-8 的軟體準備 CSV 匯出。

第三大類用途圍繞著分析。詞頻統計、搜尋索引與文字探勘都會在計算詞元前先正規化輸入,而去除腔調是該正規化的一部分。工具的等冪性保證讓它能安全地在重複執行的管線中運作:第一輪之後每次執行都是無操作,因此不會慢慢吃掉你語料庫中的字母;明確的變更計數器也讓你能快速檢查實際發生替換的數量是否正確。

貼上之前必須了解的限制

這是一個拉丁腳本的變音符號移除工具,附有明文記載的音譯規則,而不是通用的音譯器。它不會把俄文西里爾字母羅馬化、不會把希臘文轉成發音拼法、也不會把中文字元轉成拼音。折合表涵蓋的是 Unicode 字元資料庫明確從分解中省略的那些拉丁腳本字母,以及最常見的連字;像 ĸ 這類特殊字母是依慣例處理,而非依任何 Unicode 規則,這一點頁面上有明說,而不是藏著不講。

希臘文與西里爾文需要單獨提出來說明,因為它們在 Unicode 中的分解方式與帶腔調的拉丁文完全相同:ά 會被拆成 α 加上組合銳音符,ё 會被拆成 е 加上組合分音符。天真的去除器會悄悄把兩者都改寫成 α 和 е,損壞了原本的書寫系統。Remove Accents from Text 只會移除附加在拉丁字母基底上的標記,因此希臘文、西里爾文、中文、日文、韓文與天城文都會逐位元組保持原樣,而天城文的母音符號——它們在文法上本身是字母而不是腔調——也絕不會被當成可移除的標記。表情符號也是如此:它們會原封不動地保留下來,包括由多個碼點組成的國旗表情符號與膚色修飾符。

另外兩項營運細節補完這個契約。第一,輸入上限為一百萬個字元,會以單一線性方式處理,因此即使是非常大量的貼上也能快速回傳。第二,所有處理都在瀏覽器中完成——不會上傳到伺服器、不會儲存任何資料、也不需要帳號,當你正在清理的文字本身就很敏感(例如客戶名冊或私人文件)時,這一點非常重要。

若你在多方比較,How to Remove Duplicate Lines in Word Documents 有詳細說明。

若你在多方比較,How to Remove Empty Lines in a Word Document 有詳細說明。