摘要:今天要討論的是關于字符編碼的一些問題,源自一次項目周會,因網絡上沒有相關文章,現在剛好能總結一下。為招聘方宣傳以找到更多優質學生員工。延伸閱讀阮一峰字符編碼筆記阮一峰關于編碼阮一峰與字符集與字符編碼知乎和有什么區別中的坑
第一次寫segmentfault,歡迎大家提意見以便改進。
今天要討論的是關于字符編碼的一些問題,源自一次項目周會,因網絡上沒有相關文章,現在剛好能總結一下。
1. 首先來看幾張有意思的現象:
(1)? 下面這幅圖中出現一些“疊起來”的字體,來自微信公眾號“麥當勞”于2017年6月28日的推送,感興趣的同學可以去看看。
比如第一個“疊起來”的字,分別由以下兩個字體組成,其它的“特技字體”也一樣。
(2) 再看下面這個字,我把它復制粘貼到這:
小?
在Chrome瀏覽器看到的可能是下面這樣:
在iPhone微信和Safari等平臺或瀏覽器上看到的可能是:
在某些Android微信上看到的可能是:
你可以復制這個網站地址,或者可以復制字符串"小?"到不同平臺上觀察顯示的效果。
(3) 連續打兩個字符,如:
Chrome瀏覽器顯示:
Sarafi瀏覽器顯示:
在寫這篇blog的時候,我也很苦惱,怎么寫出這個"?"符號,因為經常會和前面的一個字符“疊起來”,會造成誤解。
(4) 復制“小?”到Chrome地址欄時,顯示倒是“正常”:
但是,上圖是地址欄獲得焦點時的情況,如果此時失去焦點會發生如下情況:
2. 分析
(1) 不妨先用內置的encodeURIComponent() 和 decodeURIComponent()探個究竟。
總的來說,這個“疊起來”的字符解碼之后是這個結果(為了便于查看,這里用Safari進行測試):
至于%E2%83%A0,我用Chrome控制臺輸出,因為在Safari下編輯器處理這段編碼的結果會把寫注釋的"/"疊上,如圖:
(2) 翻閱了許多資料終于在Wikipedia找到相關內容,https://en.wikipedia.org/wiki...
其中講到一些背景因素,以及一些奇葩的組合類型:
In digital typography, combining characters are characters that are intended to modify other characters. The most common combining characters in the Latin script are the combining diacritical marks (including combining accents).
Unicode also contains many precomposed characters, so that in many cases it is possible to use both combining diacritics and precomposed characters, at the user"s or application"s choice. This leads to a requirement to perform Unicode normalization before comparing two Unicode strings and to carefully design encoding converters to correctly map all of the valid ways to represent a character in Unicode to a legacy encoding to avoid data loss.
In Unicode, the main block of combining diacritics for European languages and the International Phonetic Alphabet is U+0300–U+036F. Combining diacritical marks are also present in many other blocks of Unicode characters. In Unicode, diacritics are always added after the main character, so it is possible to add several diacritics to the same character, although as of 2010, few applications support correct rendering of such combinations.
3. 看到這也大致了解了 Combining Character,不妨再看看Web開發中常見的亂碼:
有一次,我在微信公眾號開發項目中,指定回復消息為文本格式的時候,嘗試了幾種換行方式都不行,最終了解即XML的換行應使用:
是字符實體編號(16進制),可以用于處理XML中文本的換行。
對應的正確代碼在第9行(部分文字有修改):
]]> ]]> <% createTime %> ]]> <% if (msgType === "text") { if(content!=="zs") { %>]]> <% } else { %>歡迎來到報名圖書館暑假工! 報名步驟: ①將招聘推文轉發至朋友圈或者40人以上的群,讓更多同學了解本招聘。為招聘方宣傳以找到更多優質學生員工。 →點此進入招聘推文 ②回復你的資料:報名+姓名+電話號碼+深圳哪個區+可上班時間 <% }} else if (msgType === "zs") { %>ddwadwada <% } else if (msgType === "image") { %>... ]]>
由這個問題,我們想到web開發中還有一些類似的“亂碼”,這些亂碼又有哪些規律呢?
(1) 字符實體
字符實體是XML和HTML中的字符編碼方式,也就是上面事例中提到的,格式為:
& + 實體名稱 + ; & + (# + unicode編碼) + ;
實體名稱一般是有意義的詞,方便大家記憶,比如小于號<的實體名稱是lt,也就是less than的縮寫。只有部分符號是有實體名稱的,使用unicode編碼是更通用的寫法。
像文字類一般不會采用這種編碼方式,主要用于在HTML或XML文檔中輸出一些保留字符和空格,比如我想在HTML中展示一段html代碼就需要使用字符實體。
比如我們要展示
情深深雨蒙蒙
以下兩種表示是等效的:情深深雨蒙蒙</p>
情深深雨蒙蒙</p>
總而言之,字符實體是HTML和XML中的編碼方式,比如在HTML文檔中寫入:我,那么最終頁面上看到的是我這個漢字。
(2) unicode字符
編程語言中的unicode字符的格式為:
u + 16進制unicode編碼
絕大多數編程語言,包括CSS中都支持unicode字符,不過HTML和XML是不支持的。那么什么時候使用unicode字符呢?一般來說有兩種場景:
避免文件保存時采用不同編碼導致的亂碼,因為u已經聲明了是unicode。
正則匹配中的一些應用:Unicode編碼及在正則表達式中的使用
在JS中可以使用charCodeAt()獲取字符串的10進制unicode編碼
(3) URL編碼
類似%E6%88%91這樣的,叫做URL編碼,在鏈接的參數里非常常見
網絡標準RFC 1738做了硬性規定:
“只有字母和數字[0-9a-zA-Z]、一些特殊符號”$-_.+!*"(),”[不包括雙引號]、以及某些保留字,才可以不經過編碼直接用于URL。”
所以像漢字,空格這些都必須經過轉碼。上面講的unicode字符,字符實體用的都是unicode編號,而URL編碼用的則是utf-8, 規則是將utf-8編碼每隔兩個字符加一個%
UTF 是英文 Unicode Transformation Format 的縮寫,意為把 Unicode 字符轉換為某種格式。unicode和utf-8并不是同一種東西,但是又存在著聯系:unicode是信源編碼,對字符集數字化; utf-8,utf-16這些是信道編碼,為更好的存儲和傳輸。
簡單說,unicode就是一組數字,每一個數字對應一個字符。utf-8就是對字符的傳輸和保存時的規則。比如說“我”這個字,unicode碼(16進制)是6211,utf-8是E68891, 那么對應的URL編碼就是%E6%88%91;
{ Unicode編碼: 0x6211, UTF8編碼: E68891, UTF16編碼: FEFF6211, UTF32編碼: 0000FEFF00006211 URL編碼: %E6%88%91 }
(4) 本段小結:
Web開發中常見的幾種亂碼包括:Unicode字符、字符實體、URL編碼。如以下情況都表示“我”:
Unicode字符: u6211 字符實體編號(16進制):我 字符實體編號(10進制):我 URL編碼:%E6%88%91
這些編碼規則的本質都是一些特殊符號 + Unicode編碼 所組成。
4. 總結
從【1】中展示的,各種奇怪現象我們找到原因和資料是Combining Character以及編碼相關問題,其次我們也拓展了一下Web開發中常見的一些”亂碼”以及相關的技術背景。
歡迎大家指正或提意見以便改進。
5. 延伸閱讀
《阮一峰:字符編碼筆記》
《阮一峰:關于URL編碼》
《阮一峰:Unicode與JavaScript》
字符集與字符編碼
知乎:unicode和utf-8有什么區別
javascript中unicode的坑
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/90139.html
摘要:你真的會字符串反轉計算字符串長度么字符串編碼問題一個常見的問題如何將字符串反轉一個常見的解答再如,如何得到一個字符串的長度答這些答案都不是完全正確,或者說并不是對于所有的字符都是適用的,例如這其中的原因涉及到了的字符串編碼。 你真的會字符串反轉、計算字符串長度么? Javascript 字符串編碼 問題 一個常見的問題:如何將字符串反轉? 一個常見的解答: abcd.split().r...
摘要:中常用的單元測試工具是老牌測試框架了,也是目前引用最廣泛的一個框架。可以使用適當的單元測試方式,比如可以提供一個測試接口,利用的熱部署功能實現不重啟及時修改代碼。 什么是單元測試 單元測試(英語:Unit Testing)又稱為模塊測試, 是針對程序模塊(軟件設計的最小單位)來進行正確性檢驗的測試工作。程序單元是應用的最小可測試部件。在過程化編程中,一個單元就是單個程序、函數、過程等;...
摘要:字符編碼表,碼位碼元將編碼字符集中的碼位轉換成有限比特長度的整型值的序列。字符編碼方案,碼元序列化也稱為常說的序列化。每個字節里的二進制數就是字節序列。另一個情況則是壓縮字節序列的值,如或進程長度編碼等無損壓縮技術。 《流暢的Python》筆記。本篇主要講述不同編碼之間的轉換問題,比較繁雜,如果平時處理文本不多,或者語言比較單一,沒有多語言文本處理的需求,則可以略過此篇。 1. 前言 ...
閱讀 3110·2023-04-25 16:50
閱讀 916·2021-11-25 09:43
閱讀 3528·2021-09-26 10:11
閱讀 2527·2019-08-26 13:28
閱讀 2538·2019-08-26 13:23
閱讀 2432·2019-08-26 11:53
閱讀 3576·2019-08-23 18:19
閱讀 2997·2019-08-23 16:27