字元計數
「一個字元」其實是四個不同的數字。
本機處理完全在你的瀏覽器裡執行 —— 打開開發者工具的 Network 分頁就能驗證
這段文字由什麼組成
| 類別 | 數量 | 佔比 |
|---|---|---|
| 中日韓字元 | 0 | — |
| 英文字母 | 0 | — |
| 數字 | 0 | — |
| 標點與符號 | 0 | — |
| 空白 | 0 | — |
| 其他 | 0 | — |
還沒有內容 —— 輸入或貼上一些文字。
貼上文字,一次拿到所有可能被要求的數字:Unicode 碼位、UTF-16 編碼單位、看得見的字元、UTF-8 位元組,含空白與不含空白都有。它們不是同一個數字,而你該用哪一個,取決於是誰在執行那個上限。
「幾個字元」為什麼不只有一個答案
碼位是 Unicode 表裡的一個條目。UTF-16 編碼單位是 JavaScript、Java、C# 與多數資料庫實際的儲存方式 —— 而 U+FFFF 以上的字元(所有 emoji,以及較罕用的 CJK 擴充區漢字)每個要佔兩個單位。「看得見的字元」是讀者會指著說「這是一個字」的東西,它可能由好幾個碼位黏起來。UTF-8 位元組則是真正在網路上傳輸、真正佔硬碟的那個量。
純英文的情況下這四個數字完全相同,所以多數工具只給一個,也從來不提這件事。但只要文字裡出現一個 emoji、一個在 Mac 上打出來的重音字母,或者一個中文字,它們就分岔了 —— 而一個給你數字卻不告訴你那是哪一種的工具,等於給了一個你沒辦法拿去用的數字。
你要貼進去的那個地方,到底在算哪一個
表單的 maxlength、以及多數以「字元」宣告的資料庫 VARCHAR 欄位,算的是 UTF-16 編碼單位 —— 這就是為什麼一個收得下 20 個英文字母的欄位,會退掉 15 個 emoji。而以「位元組」宣告的欄位(舊系統與部分 MySQL 設定很常見)算的是 UTF-8 位元組,一個中文字是 3 個,所以「30 位元組」的欄位裝得下 10 個中文字,不是 30 個。
台灣的實務上還有兩個常見情境:政府與銀行的線上表單很多是舊系統改的,姓名欄位常常以位元組計,中文名字四個字就吃掉 12 個;出版合約與翻譯報價則幾乎都用「不含空白的字元數」,也就是這一頁的第二個數字。上限真的會被執行的時候,請用執行者的定義去算,不要用對自己草稿比較有利的那個。
你看不見的那些字元
從網頁、PDF 或文書軟體複製過來的文字,經常夾帶乘客:用來提示斷行的零寬空格、軟連字號、位元組順序記號、左右書寫方向標記,以及中文與日文輸入法會產生的全形空白 U+3000。每一種長度檢查都會算它們,而你一個都看不到。
這一頁把它們單獨列成一個數字,因為它們通常就是某個怪事的解答:兩個看起來一模一樣的字串比對失敗、明明重複卻去不掉的資料列、螢幕上看得到卻搜尋不到的詞、看起來明顯沒超過上限卻被退回的表單 —— 幾乎都是隱形字元。其中全形空白最陰險,因為只 trim ASCII 空白的程式碼完全清不掉它。
同一個詞,兩種存法
一個帶重音的字母可以是一個碼位,也可以是「字母 + 組合附加符號」兩個碼位,畫出來一模一樣。macOS 的檔案系統歷來偏好分解形式,而 Windows 與多數網頁輸入產生的是組合形式,所以同一個檔名可能以兩種編碼抵達,然後比對出「不相等」。
這一頁的「碼位數」與「看得見的字元」不一致時,你看到的就是這件事。解法是比較之前把兩邊正規化成同一種形式;想知道多出來的碼位到底在哪一個位置,用我們的 Unicode 字元檢視逐字看最快。
在這裡算,不在伺服器上算
計算就是幾個字串運算,跑在這個分頁裡。沒有上傳、不必排隊,除了你自己的記憶體之外沒有大小上限,而且把網路關掉頁面照樣能算 —— 那是「什麼都沒送出去」最簡單的證明。
這件事對這個工具特別重要,因為人們貼進來的東西是:有字數上限的合約草稿、求職自述、考試作答、內部公告、還沒上市的產品文案。伺服器端的計數工具會收到全部這些內容,這一個收不到。
常見問題
為什麼我的 emoji 被算成 2?
因為它是用「代理對」儲存的 —— 一個碼位佔兩個 UTF-16 編碼單位。這一頁同時給你兩個數字與「看得見的字元」,你可以看出哪一個上限會卡到你。
為什麼跟 Word 的字元數不一樣?
Word 用的是它自己的定義,對中文與空白也有自己的處理方式。如果那個上限是「有人用 Word 打開你的檔案」在把關,就用 Word 算;如果是程式在把關,用這一頁。
一個中文字是幾個位元組?
UTF-8 是 3 個,罕用的擴充區漢字是 4 個。所以以位元組為單位的欄位,實際能裝的中文比數字看起來少很多 —— 這也是這一頁要列出 UTF-8 位元組的原因。
空白算進去嗎?
兩個數字都給。不含空白的那個會扣掉所有種類的空白,包括只 trim ASCII 空白時清不掉的全形空白 U+3000。
我的文字會被上傳嗎?
不會。計算在這個分頁裡用 JavaScript 執行。打開開發者工具的 Network 分頁然後打字 —— 不會有任何請求,而且把網路關掉它照樣算得出來。