天天看點

Unicode字元編碼标準

Unicode

1. 編碼知識 

1.1 文本和字元 

在計算機程式中或者資料檔案裡,文本(text)是作為數字序列存儲的。序列中的數字是具有不同大小、取值和解釋的整數。如何解釋這些整數是由字元集(character set)、編碼(encoding)決定的。 

文 本主要是由字元(character)組成。在格式文本(fancy text, or rich text)中包括顯示屬性,如顔色、斜體字、上标等,但仍然是以字元組成的純文字(plain text)為基礎的。有時,格式文本與純文字之間的差別很複雜,依賴于具體的應用。 

什麼是字元?典型地,是字母。也可以是數字、句點、連字号、标點符号和數學符号,對于中文,也可以是漢字。還包括定義行尾和段落等的控制字元(一般不可見)。 

有了字元,就可以為它們配置設定數字編碼。為字元配置設定什麼數字值,依賴于具體情況。一個簡單的字元,如字母"a",在不同的程式或者資料檔案中可能具有不同的整數值。 

1.2 字元集:具有數字編碼的字元 

在資訊進行中,所使用的整數總有上限,依賴于存儲整數的位的數目。這也決定了可以同時區分的字元的數量。 

在設計字元集時,首先要決定所需字元的數目,并确定所需字元的清單。根據字元的數目,可以設定整數值的上限,這個整數範圍稱為編碼空間(code space),其中的一個特定整數稱為一個碼點(code point)。 

然後,為字元清單中的每個字元指定一個整數值,也就是一個碼點。這樣就得到一個字元集,稱作編碼字元集(Coded Character Set)。 

1.3 編碼單元、位元組和編碼 

在 計算機系統的實作中,整數以特定大小的單元表示,通常為8位(1位元組),16位,或32位。在字元編碼中,這樣的單元稱為編碼單元(code unit)。根據編碼空間的大小和具體要求,來選擇合适的編碼單元。通常,所選擇編碼單元對應的整數範圍要大于編碼空間的整數範圍,這樣每個碼點就隻需一 個編碼單元表示,并且在字元碼點與編碼單元間的轉換非常簡便,因為字元碼點對應的整數值與相應編碼單元的整數值相同。如果編碼單元對應的整數範圍小于編碼 空間的整數範圍,就需要多個編碼單元表示一個碼點。 

位元組是計算機系統中最基本的表示單元,無論是存儲在記憶體中,還是将文本寫入檔案或通過網絡發送,總是要讀寫若幹位元組。是以,在實際應用中,還需要将編碼單元進一步表示為位元組序列。 

将字元表示為位元組序列的過程就稱為編碼(encoding),更重要的是,還包括如何對位元組序列進行解釋以取得字元。 

1.4 不同的字元集 

在一些常用的編碼中,每個字元隻使用一個位元組表示,稱單位元組字元集(single-byte character set, SBCS)。這些字元集都僅限于256個字元。 

在ASCII之後,目前應用最廣泛的單位元組字元集是ISO-8859-1。它是ASCII的一個8位超集,并且提供西歐語言所需的大多數字元。它的一個改進的版本,ISO-8859-15,還包括新的歐元符号和更多的一些法語和芬蘭語字母。 

    雙位元組字元集(double-byte character set, DBCS)用于為東亞書寫系統中所使用成千上萬個表意字元提供足夠空間。這裡的編碼仍是基于位元組的,不過是兩個位元組一起表示一個單一的字元。 

    即使在東亞,文本中也會包含小字母表中的字母,如拉丁字母表。這些字母使用單位元組表示的效率會更高。是以,提出了多位元組字元集(multi-byte character set, MBDC),使用可變數目的位元組來表示字元。多位元組字元集通常與ASCII相容,也就是說,在這種編碼中,拉丁字母使用與ASCII中相同的位元組來表示。 一些不常用的字元可能會使用三個甚至四個位元組編碼。 

1.4 常見字元集 

1.4.1 ASCII: The American Standard Code form Information Interchange 

    ASCII是一個使用7位單元的字元集,及針對7位位元組的簡單編碼方式。盡管局限于很少的一些字元,ASCII是最重要的一種字元集,因為它是目前大多數字元集的基礎。 

    ASCII隻提供了128個數字值(也可稱作碼點,code point),其中33個被保留用作特殊功能。隻有95個碼點用作"真正的"文本字元。這些圖形字元大多時大寫和小寫拉丁字母,數字和标點符号,外加一些特殊的括号、下劃線和重音符号。 

1.4.2 EBCDIC: The Extended Binary-Coded Decimal Interchange Code 

EBCDIC是由IBM設計的編碼格式,使用8位位元組,被一些字元集用于大型機。EBCDIC在與ASCII相近的時期開發的,具有一些相似的特性。 

1.4.3 Unicode 

Unicode标準定義了一個字元集和幾種編碼。 

Unicode最有吸引力的特點是它涵蓋了幾乎世界上的所有字元,可以隻通過一個唯一的數字(Unicode碼點)來通路和操作字元。 

2. Unicode介紹 

2.1 為什麼使用Unicode? 

在創造Unicode之前,有數百種編碼系統。但是,沒有任何一個編碼可以包含足夠的字元。例如,僅歐州共同體就需要好幾種不同的編碼來包括所有的語言。即使是單一的一種語言,如英語,也沒有哪一個編碼可以适用于所有的字母,标點符号,和常用的技術符号。 

這些編碼系統也會互相沖突。也就是說,兩種編碼可能使用相同的數字代表兩個不同的字元,或使用不同的數字代表相同的字元。任何一台特定的計算機(特别是伺服器)都需要支援許多不同的編碼,但是,不論什麼時候資料通過不同的編碼或平台之間,那些資料總會有損壞的危險。 

而Unicode正在改變所有這一切! 

在Unicode标準中,提供了1,114,112個碼點,不僅可以包含當今世界使用的所有語言文字和其他符号,也足夠容納絕大多數具有曆史意義的古文字和符号。并且,Unicode給每個字元提供了一個唯一的數字,不論是什麼平台,不論是什麼程式,不論什麼語言。 

Unicode 标準已經被工業界的上司們所采用,例如:Apple, HP, IBM, JustSystem, Microsoft, Oracle, SAP, Sun, Sybase, Unisys等等。最新的标準都需要Unicode,例如XML, Java, ECMAScript , LDAP, CORBA 3.0, WML等等,并且,Unicode是實作ISO/IEC 10646的正規方式。許多作業系統,所有最新的浏覽器和許多其他産品都支援它。Unicode标準的出現和支援它工具的存在,是近來全球軟體技術最重要 的發展趨勢。 

2.2 Unicode與國際化 

直到最近,國際化的常用方法是,假定任何給定的可執行程式同時隻和一種語言工作。如果在英文環境下安裝,它就隻處理英文文本;如果在中文環境下安裝,就隻進行中文文本。 

在 這種模型下,針對不同的書寫系統和語言,使用的字元集和字元編碼不同。在Windows和大型機環境下,術語"代碼頁"(Code Page)用于描述如何将二進制值映射到人類可讀得字元(字形)。一個運作的程式處在單一的代碼頁,該代碼頁确定二進制值如和與字形關聯。 

簡便的國際化是Unicode的另一項優勢。在内部使用Unicode的應用程式,能夠同時存儲和處理世界上所有的字元,這消除了傳統的國際化方法所面臨的一些困難。 

當然,成功的國際化不僅僅是在應用程式中采用Unicode,還需要謹慎的螢幕布局設計(不同的語言具有不同的書寫習慣)、翻譯和文化了解。 

2.3 設計原則 

Unicode的設計反映了十大基本原則,但這些原則并不是可以同時滿足。整個設計是在保證簡便高效和保持與已有編碼标準相容之間的平衡。 

(1)廣泛性(Universality) 

Unicode标準對一個單一的大字元集進行編碼,包括滿足世界範圍需求的所有字元。 

(2)高效(Efficiency) 

在Unicode的字元編碼模型中沒有換碼符(escape character),每個字元編碼與其它字元編碼具有相同的狀态。使高效率的實作成為可能。 

所有Unicode編碼方式都是自同步的,并且互相不重疊。使在字元流中随機通路和查找操作高效。 

同一書寫字母體系中的字元被放置在一起,不僅友善字元的查找,并且使實作更緊湊壓縮方法更高效。 

(3)針對字元編碼,而不是字形(Character, Not Glyph) 

字元是書寫語言中具有語義的最小元件的抽象表示。字元是以駐留在記憶體中的碼點表示。 

字形是字元被顯示時具有的形狀。與字元相比,字形出現在螢幕或紙張上作為一個或多個字元的特定表示。字形的集合構成一種字型。 

字元和字形間存在多種關系:一個字形可以對應一個字元;一個字形也可以對應幾個字元;多個字形也可能出自一個字元。 

(4)語義(Semantic) 

在Unicode中,字元都有明确定義的語義。字元屬性表可用于解析、排序等需要有關碼點語義知識的算法中。Unicode中定義的屬性包括數字、間隔、組合和方向屬性。 

(5)純文字(Plain Text) 

純文字或無格式文本,僅僅是字元編碼的序列。純Unicode文本就是Unicode編碼的序列。而格式文本(styled text, or rich text)是由純文字添加一些附加資訊(如語言辨別、字型大小、顔色等)組成的文本表示。 

Unicode标準針對的是純文字。 

(6)邏輯順序(Logical Order) 

Unicode文本在記憶體表示中以邏輯順序存儲,大緻對應于借助鍵盤輸入文本的順序。在一些情況下,當顯示或列印文本時,字元順序與邏輯順序不同。 

(7)統一(Unification) 

Unicode标準為避免對字元重複編碼,對不同語言書寫方式中的字元進行統一,相同的字元配置設定唯一的一個編碼。普通字母、标點符号、标記,和變音符都隻配置設定一個編碼,而不管語言;同樣的還有中日韓使用的表意字元。 

(8)動态組合(Dynamic Composition) 

Unicode标準允許加重音符好的形式和Hangul音節的動态組合。 

(9)等價序列(Equivalent Sequences) 

一些文本元素即可以使用靜态的預先組合好的形式,也可使用動态組合的形式。Unicode字元的不同表示序列被認為是等價的。 

如果兩個或多個序列被認為是等價的,Unicode标準不規定哪一種特定的序列是正确的,而認為每一個序列隻不過與其它序列等價。 

如 果需要一種單一的單一的表示方式,可以使用一種規範化的Unicode文本形式來減少不想要差別。Unicode标準定義了四種規範化形式: Normalization Form D (NFD),Normalization Form KD (NFKD),Normalization Form C (NFC),和Normalization Form KC (NFKC)。大約來說,NFD和NFKD将可能的字元進行分解,而NFC和NFKC将可能的字元進行組合。 

(10)可轉換性(Convertibility) 

在Unicode 标準和其他字元集标準之間可以實作準确的轉換。一般說,在其他标準中的一個碼點對應于Unicode标準中一個單一的碼點。然而,有時在其他标準中的一個 碼點對應于Unicode标準中一個碼點的序列。在Unicode文本和其他字元編碼文本間的轉換一般是通過明确的表映射過程完成的。 

2.4 Unicode的碼點、編碼格式、編碼方案 

2.4.1 Unicode編碼空間和碼點 

在Unicode标準中,編碼空間的整數範圍是從0到10FFFF(16進制),共1,114,112個可用的碼點。 

為了與已有的編碼标準相容,一些抽象字元可能會與多個分别編碼的字元關聯。而在其他一些情況下,一個抽象字元可能會用兩個(或更多)編碼字元序列來表示,如帶重音符的字母。 

2.4.2 Unicode編碼格式 

在Unicode字元編碼模型中,編碼格式(encoding form)指定如何将每個碼點表示為一個或多個編碼單元序列。Unicode标準提供了三種不同的編碼格式,使用8位、16位和32位編碼單元,分别為UTF-8、UTF-16、UTF-32。 

(1)UTF-32 

UTF-32是一種最簡單的Unicode編碼格式。每個Unicode碼點被直接表示為一個32位的編碼單元。UTF-32是一種固定寬度的字元編碼格式。 

每個UTF-32編碼單元的值與Unicode碼點的值完全相同。 

(2)UTF-16 

在UTF-16中,在範圍U+0000到U+FFFF間的碼點使用一個單一的16位編碼單元表示;而,在範圍U+10000到U+10FFFF間的碼點則使用一對16位編碼單元表示,稱作代理對(surrogate pair)。 

UTF -16優化了基本多語言平面(Basic Multilingual Plane)中字元的表示,即位于U+0000到U+FFFF範圍内的字元。該範圍包含了目前世界上所使用的書寫系統中的絕大多數字元,每個字元隻需要一 個16位的編碼單元。對于基本多語言平面,UTF-16可作為固定寬度的編碼格式來有效使用。 

但對于增補字元,UTF-16需要兩個16位的編碼單元,意味着正式的UTF-16是一個變寬的編碼格式。 

UTF-16是早期Unicode遺留下的曆史産物,原本被設計成具有固定寬度的16位編碼格式。為支援超過U+FFFF的增補字元,設立了代理機制。 

(3)UTF-8 

為滿足基于ASCII,面向位元組的系統的需要,Unicode标準中定義了第三種編碼格式UTF-8。它是一種使用8位編碼單元的變寬的編碼格式。 

在UTF-8的編碼單元種,一些高位用于訓示目前位元組在編碼單元序列中的那一部分。8位編碼單元的取值的一部分範圍保留給UTF-8的編碼單元序列的首位元組;另一部分完全奮力的範圍保留給序列中的後續位元組,以保證UTF-8不重疊。 

UTF -8編碼格式對所有ASCII碼點具有透明性。在U+0000到U+007F範圍内的Unicode碼點,被轉換為UTF-8中單一的位元組0x00到 0x7F,與ASCII碼沒有差別。并且,從0x00到0x7F不會出現在其他Unicode碼點的UTF-8表示中的任一位元組中,保證了不存在歧義。 

Unicode中超出ASCII範圍的其他一些非表意字母,每個都在UTF-8種使用量各位元組表示;位于U+0800到U+FFFF範圍内的非代理碼點使用三位元組表示;超出U+FFFF的增補碼點則需要四位元組表示。 

UTF-8是Internet中HTML和類似協定偏好的編碼格式。 

UTF-8同其他的多位元組編碼方式相比具有以下特點: 

a) UTF-8的編碼單元序列的第一個位元組指明了後面所跟的位元組的數目。對前向解析非常有效。 

b) 從UTF-8位元組流的任意位置開始可以有效的找到一個字元的其實位置。 

c) UTF-8中不存在位元組取值的重疊。 

2.4.3 Unicode編碼方案 

在Unicode标準中,用于Unicode資料位元組串行化的各種不同類型的規範被稱為Unicode編碼方案(encoding scheme)。 

在計算機系統中,大數值類型(如整型)使用多個位元組表示,不同體系結構采用的位元組排列順序不同。其中,部分采用由高位元組到低位元組的排列順序,稱為big-endian;其他則采用由低位元組到高位元組的排列順序,稱little-endian。 

對于UTF-16和UTF-32,位元組串行化規範必須考慮目前表示資料的系統采用的是big-endian還是little-endian結構。 

一個字元編碼方案包括指定的字元編碼格式,以及如何将編碼單元串行化為位元組的規範。在Unicode标準中,還規定了初始的位元組順序标志(byte order mark, BOM)的使用,用于顯示區分big-endian和little-endian資料。 

對于UTF-8,在序列中隻包括UTF-8的編碼單元(1位元組),是以,UTF-8中的資料表示不存在位元組順序的問題。但對于16位和32位的編碼方案,位元組串行化過程必須将編碼單元分解為兩個或四個位元組,并且必須清楚的定義這些位元組的順序。 

是以,Unicode标準中定義的三種編碼格式,導緻總共七種Unicode編碼方案,分别為:UTF-8、UTF-16、UTF-16BE、UTF-16LE、UTF-32、UTF-32BE、UTF-32LE。 

必須明确,字元編碼格式(character encoding form)指在記憶體或API中的整數資料單元,與位元組順序不相關;字元編碼方案(character encoding scheme)指位元組串行化的資料,如I/O流或者檔案,必須制定位元組順序。 

2.4.4 Unicode編碼空間配置設定 

根據在語言學上和功能上的類别,Unicode标準中的編碼字元被分成組。 

Unicode 編碼空間的範圍為0到10FFFF,可以被劃分為字元平面(planes of characters),每個平面包含64K各碼點。是以,最底層的平面為基本多語言平面(Basic Multilingual Plane),包括範圍從0000到FFFF;下一個平面為增補多語言平面(Supplementary Multilingual Plane),也被稱為第一平面(Plane 1),包括範圍10000到1FFFF;以及,第二平面(Plane 2),增補表意字元平面(Supplementary Ideographic Plane),包括範圍20000到2FFFF;等等。基本多語言平面有時也被稱為Plane 0。 

基本多語言平面(BMP, or Plane 0)包含目前世界上使用的所有書寫系統中的全部常用字元,以及一些曆史上的不常用字元。 

增補多語言平面(SMP, or Plane 1)用于一些較少使用的曆史上的書寫系統,針對特殊目的建立的書寫系統,和特殊的标記系統,它們要麼無法放入基本多語言平面中,要麼特别不常用。 

增補表意字元平面(SIP, or Plane 2)用于無法放入基本語言平面衆所配置設定區域中/日/韓字元(CJK character)。盡管在SIP中包含少量的常用CJK字元(例如,用于粵語),其中絕大多數字元是僅具有曆史意義的不常用字元。 

增補專用平面(Supplementary Special-purpose Plane, SSP, or Plane 14)用于無法放入基本多語言平面衆所配置設定區域的格式控制字元。 

3. 一緻性 

符合Unicode一緻性要求的實作必須滿足本部分定義的标準,以便與其他規範的實作進行互動。 

3.1 一緻性要求 

3.1.1 未配置設定的碼點(Unassigned Code Points) 

C4 處理過程不應該把高代理碼點(high-surrogate code point)或者低代理碼點(low-surrogate code point)解釋為抽象字元。 

C5 處理過程不應該把非字元碼點解釋為抽象字元。 

C6 處理過程不應該将未配置設定的碼點解釋為抽象字元。 

3.1.2解釋(Interpretation) 

C7 如果處理過程要解釋編碼字元的表示,就必須根據标準中确立的字元語義進行解釋。 

C8 不要求處理過程對任何特定的編碼字元都作解釋。 

  允許處理過程隻解釋Unicode字元中的一個子集;不需要解釋所有Unicode字元。 

  标準中不涉及任何指定字元子集的方法。 

  标準中不涉及自定義區中碼點的語義。 

C9 處理過程不應認為對兩個具有規範等價性字元序列(canonical-equivalent character sequence)的解釋會不同。 

  該條款包含兩層意義:(一)處理過程不應該對兩個不同但又具有規範等價性的字元序列由不同的解釋;(二)任何處理過程不應假設其他處理過程會對兩個不同但具有規範等價性的字元序列進行不同的解釋。 

3.1.3 修改(Modification) 

C10 如果一個處理過程聲稱不會修改對一個正确的編碼字元表示的解釋,則它不能對編碼字元的表示進行任何修改,除非是用具有規範等價性的字元序列進行替換,或者是删除非字元的碼點。 

  用具有規範等價性的字元序列替換原有字元序列不會修改對文本的解釋。 

  替換或者删除處理過程不能會不進行解釋的字元序列,不修改對文本的解釋。 

  當在不同計算機體系結構間轉換字元序列時,對字元序列位或者位元組順序的改變,不修改對文本的解釋。 

  将一個正确的編碼字元的表示從一種Unicode字元編碼格式轉換為另一種編碼格式時,不修改對文本的解釋。 

  将編碼單元序列的位元組串行化從一種Unicode字元編碼方案轉換為另一種編碼方案時,不修改對文本的解釋。 

  如果在處理過程中意外遇到一個沒有明确内部用途的非字元,在實作中可以發出錯誤,或者删除或忽略該非字元。如果沒有采取這些選擇,這個非字元應該被作為一個為配置設定的碼點。 

3.1.4 字元編碼格式(Character Encoding Forms) 

C11 當處理過程對一個聲稱以某種Unicode字元編碼格式存在的編碼單元序列進行解釋時,必須按照相應的碼點序列進行解釋。 

C12 當處理過程以某種Unicode字元編碼格式生成編碼單元序列時,不應生成形式錯誤(ill-formed)的編碼單元序列。 

C12a 當處理過程對一個聲稱以某種Unicode字元編碼格式存在的編碼單元序列進行解釋時,應該将形式錯誤的編碼單元序列看作錯誤條件,而不能将序列解釋為字元。 

3.1.5 字元編碼方案(Character Encoding Schemes) 

C12b 當處理過程對一個具有某種Unicode字元編碼方案的位元組序列進行處理時,應該根據位元組順序和标準中針對字元編碼方案設立的位元組順序标記(byte order mark)使用規範,進行解釋。 

3.1.6 雙向文本(Bidirectional Text) 

C13 用于顯示包含從右到左的字元文本的處理過程,當沒有高層協定時,必須以對文本應用雙向算法後同樣的順序顯示所有具有可見表示的字元(不包括格式字元)。 

3.1.7 正規化形式(Normalization Forms) 

C14 以某種正規化形式生成Unicode文本的處理過程,必須與Unicode Standard Annex #15 "Unicode Normalization Forms"中定義的規範相符合。 

C15 測試Unicode文本是否具有某種正規化形式的處理過程,必須與必須與Unicode Standard Annex #15中定義的規範相符合。 

C16 将文本轉換為某種正規化形式的處理過程必須生成Unicode Standard Annex #15中規定的結果。 

3.1.8 标準的引用(Normative References) 

C17 對标準、屬性别名、屬性值别名或者Unicode算法的标準引用,必須依照Unicode标準種指定的格式。 

C18 高層協定不能對臨時屬性進行标準引用。 

3.1.9 Unicode算法(Unicode Algorithms) 

C19 如果處理過程聲稱實作某個Unicode算法,則必須符合标準中定義的算法規範,除非被高層協定改變。 

3.2 術語定義 

以下是對一緻性條款中所使用術語的準确定義。 

3.2.1 字元的身份和語義(Character Identity and Semantics) 

D1 标準的行為(normative behavior):Unicode标準中的标準行為包括以下清單,以及在一緻性條款種指定的其他行為。 

1. 字元組合; 

2. 規範化的分解; 

3. 相容的分解; 

4. 規範的排序行為; 

5. 雙向行為; 

6. 聯合jamo行為(conjoining jamo behavior); 

7. 變化選擇; 

8. 正規化。 

D2a 字元身份(character identity):一個字元的身份是由它的字元名稱、表示的字形确定的。 

D2b 字元語義(character semantics):一個字元的語義是由它的身份、标準的屬性和行為決定的。 

3.2.2 字元與編碼(Characters and Encoding) 

D3 抽象字元(abstract character):資訊的單元,用于文本資料的組織、控制或表示。 

  抽象字元沒有具體的形狀,不應與字形混淆。 

  Unicode标準中沒有直接編碼的抽象字元經常可以使用組合字元序清單示。 

D4 抽象字元序列:抽象字元的有序序列。 

D4a Unicode編碼空間(Unicode codespace):從0到10FFFF的整數空間(十六進制)。 

D4b 碼點(code point):Unicode編碼空間中的任何一個整數值。 

  一個碼點也稱為一個編碼位置。 

D5 編碼字元(encoded character):在一個抽象字元和一個碼點間的關聯。 

  在Unicode中,為了與其它标準相容,一個單個的抽象字元可能與多個碼點對應。 

  一個單個的抽象字元也可能使用一個碼點序清單示。 

D6 編碼字元表示(coded character representation):一個碼點序列。通常,是由編碼字元的序列組成,但也可能包含非字元或保留的碼點。 

  編碼字元表示也稱為編碼字元序列(coded character sequence)。 

  在内部,處理過程可能會在編碼字元表示中使用非字元碼點。但是,這些非字元碼點可能不會被解釋成抽象字元;并且,如果這些非字元碼點被具有一緻性的處理過程删除,不構成對編碼字元表示解釋的修改。 

D7a 不贊成使用的字元(deprecated character):強烈不鼓勵使用的編碼字元。 

  在标準中保留不贊成使用的字元,以便使以前相容的資料仍然與今後的Unicode标準保持一緻性。 

D7b 非字元(noncharacter):被永久保留做内部使用的碼點,不應用于交換。非字元包括值U+nFFFE和U+nFFFF(n表示十六進制整數從0到10),以及值從U+FDD0到U+FDEF。 

D7c 保留的碼點(reserved code point):Unicode标準中保留的,用于今後配置設定的碼點。也稱為位配置設定碼點(unassigned code point)。 

  代理碼點和非字元碼點是已配置設定的碼點,但不是配置設定給字元。 

D8 高層協定(higher-level protocol):任何超出Unicode标準範圍,對Unicode字元進行解釋協定。 

D8a Unicode算法(Unicode Algorithm):對處理過程的邏輯描述,用于獲得涉及Unicode字元的指定結果。 

3.2.3 屬性(Properties) 

(1)标準的和訓示性屬性(Normative and Informative Properties) 

Unicode字元屬性可以分為标準的和訓示性的。 

D9 标準屬性(normative property):Unicode字元屬性,它的取值必須為與标準相一緻。 

D9a 訓示性屬性(Informative property):Unicode字元屬性,它的取值僅僅是為了提供更多資訊。 

D9b 臨時的屬性(provisional property):Unicode字元屬性,它的取值未被準許、試驗性的,也可能是不完全的。 

(2)簡單的和衍生出的屬性(Simple and Derived Properties) 

D9c 簡單屬性(simple property):Unicode字元屬性,它的取值在UCD,the Unicode Character Database(或标準中的其他地方)直接指定,并且它的取值無法從其他簡單屬性中衍生出來。 

D9d 衍生屬性(derived property):Unicode字元屬性,它的取值可通過算法從一些簡單屬性的組合中衍生出來。 

(3)屬性别名(Property Aliases) 

D10 屬性别名(property alias):特定Unicode字元屬性的一個唯一标示名。 

  用于屬性别名的标示名中僅包含ASCII中的字母、數字和下劃線。 

  為每個屬性别名分别定義了長、短兩種形式的名稱。短的形式一般隻有兩個或三個字元長,便于在标記語言中用于标記屬性。 

D10a 屬性值别名(property value alias):為Unicode字元屬性的特定取值定義的唯一标示名。 

  用于屬性值别名的标示名中僅包含ASCII中的字母、數字和下劃線,或者是特殊的值"n/a"。 

  為每個屬性值别名分别定義了長、短兩種形式的名稱。 

  屬性值别名僅在相關聯的特定屬性環境中唯一。 

(4)卻省屬性值(Default Property Value) 

D11 卻省屬性值(default property value):針對一個給定的Unicode屬性,用于指派給未配置設定的碼點或沒有明确指定其他屬性值的屬性值。 

(5)私用(Private Use) 

D12 私用碼點(private-use code point):在範圍U+E000到U+F8FF、U+F0000到U+FFFFD和U+100000到U+10FFFD内的碼點。 

  私用碼點被認為已配置設定給字元,但标準中沒有指定對私用碼點相關聯的抽象字元的解釋。 

  私用碼點可能會被賦予卻省的屬性值,但這些卻省值可以被對私用碼點進行解釋的高層協定替換。 

3.2.4 組合(Combination) 

D13 基字元(base character):在書寫上,不與前面的字元進行組合的字元,它既不是控制字元也不是格式字元。 

D14 組合字元(combining character):在書寫上,與前面的基字元進行組合的字元。稱組合字元應用于基字元。 

  組合字元不單獨使用。它們包括重音符、變音符、希伯萊文中的點、阿拉伯文元音符号等。 

  盡管組合字元用來與基字元組合顯示的,但可能出現兩種情況(1)在組合字元前沒有基字元;(2)處理過程無法執行組合操作。在這兩種情況下,處理過程可能會不進行書寫上的合并而顯示組合字元。 

  在編碼表中,組合字元的表示使用虛線圓圈描繪。當與前面的基字元組合顯示時,基字元要出現在虛線圓圈的位置上。 

  組合字元一般具有它們的基字元的屬性,同時保留它們的組合屬性。 

  控制字元和格式字元,如tab和right-left mark不是基字元。 

D15 非間距标記(nonspacing mark):在顯示時,位置取決于基字元的組合字元。這些字元一般在可視基線上不占用空間。 

  這些字元可能會很大,影響它們的基字元相對于前後基字元的放置。 

D16 間距标記(spacing mark):不是非間距标記的組合字元。 

  一般來說,間距标記的行為與基字元沒有太大差別。 

D17 組合字元序列(combining character sequence):一個字元序列,由一個基字元後跟了一個或多個組合字元組成,或者是一個或多個組合字元的組成的序列。 

D17a 不良的組合字元序列(defective combining character sequence):一個不是以基字元開始的組合字元序列。 

  當組合字元序列出現在串的開始位置,或者跟在控制字元或格式字元後出現時,産生不良的組合字元序列。 

3.2.5 分解(Decomposition) 

D18 可分解字元(decomposable character):根據分解映像表,與一個或多個字元組成的序列等價的字元。也被稱作預組合字元(precomposed character)或複合字元(composite character)。 

D19 分解(decomposition):與一個可分解字元等價的一個或多個字元組成的序列。一個字元序列的完全分解,是對序列中每個字元進行分解直到沒有字元可以進一步分解。 

(1)相容的分解(Compatibility Decomposition) 

D20 相容的分解(compatibility decomposition):遞歸應用Character Names List中的相容映像表和規範映像表,以及Conjoining Jamo Behavior中的定義,對字元進行分解,直到沒有任何字元可以進一步分解,并根據Canonical Ordering Behavior中的定義對非間距标記進行重新排序。 

D21 相容的可分解字元(compatibility decomposable character):相容分解的結果與規範分解結果不相同的字元。 

(2)規範的分解(Canonical Decomposition) 

D23 規範的分解(canonical decomposition):遞歸應用Character Names List中的規範映像表,以及Conjoining Jamo Behavior中的定義,對字元進行分解,直到沒有任何字元可以進一步分解,并根據Canonical Ordering Behavior中的定義對非間距标記進行重新排序。 

D21 規範的可分解字元(compatibility decomposable character):與規範分解結果不相同的字元。 

D24 規範等價性(canonical equivalent):如果兩個字元序列的完全規範分解結果相同,稱它們具有規範的等價性。 

3.2.6 代理(Surrogates) 

D25 高代理碼點(high-surrogate code point):位于範圍U+D800到U+DBFF内的Unicode碼點。 

D25a 高代理編碼單元(high-surrogate code unit):在範圍D800到DBFF内的16位編碼單元,作為UTF-16中代理對的起始編碼單元。 

D26 低代理碼點(low-surrogate code point):位于範圍U+DC00到U+DFFF内的Unicode碼點。 

D26a 低代理編碼單元(low-surrogate code unit):在範圍DC00到DFFF内的16位編碼單元,作為UTF-16中代理對的結尾編碼單元。 

D27 代理對(surrogate pair):由兩個16位編碼單元組成的序列來表示單個的抽象字元,其中,代理對的第一部分為高代理編碼單元,第二部分為低代理編碼單元。 

  代理對僅用于UTF-16。 

  孤立的代理編碼單元自身沒有解釋。 

3.2.7 Unicode編碼格式(Unicode Encoding Forms) 

D28 Unicode标量值(Unicode scalar value):除了高代理和低代理碼點外的其他所有Unicode碼點。 

D28a 編碼單元(code unit):為了處理和交換,表示編碼文本單元的最小的位組合。 

  編碼單元是計算機存儲中的特定單元。Unicode标準在UTF-8中使用8位編碼單元,在UTF-16中使用16位編碼單元,在UTF-32中使用32位編碼單元。 

  在Unicode标準中,一些編碼單元的特定值不能單獨用于表示編碼字元。該限制條件應用于UTF-16中孤立的代理碼點,以及UTF-8中的位元組80-FF。 

D28b 編碼單元序列(code unit sequence):一個或多個編碼單元的有序序列。 

  當編碼單元是8位時,編碼單元序列也可被稱作位元組序列。 

  一個編碼單元序列可能隻有一個單個的編碼單元。 

  在程式設計語言中,字元串類型的值基本由編碼單元序列組成。 

  依賴字元編碼标準的結構,可能要使用編碼單元序列(包含多個編碼單元)來表示一個單個的編碼字元。 

D29 Unicode編碼格式将每個Unicode标量值配置設定給一個唯一的編碼單元序列。 

  由于曆史原因,Unicode編碼格式也被稱作Unicode(or UCS) transformation formats(UTF)。 

  在Unicode标量值集合與針對Unicode編碼格式的編碼序列集合間的映射是一對一的。 

  對給定的編碼格式,存在編碼單元序列沒有相關聯的Unicode标量值。 

D29a Unicode串(Unicode string):由Unicode編碼格式中編碼單元組成的編碼單元序列。 

D29b 8位Unicode串(Unicode 8-bit string):隻包含UTF-8編碼單元的Unicode串。 

D29c 16位Unicode串(Unicode 16-bit string):隻包含UTF-16編碼單元的Unicode串。 

D29d 32位Unicode串(Unicode 32-bit string):隻包含UTF-32編碼單元的Unicode串。 

D30 形式不良的(ill-formed):如果具有Unicode編碼格式的Unicode編碼單元序列沒有遵照Unicode編碼格式規範,就稱為形式不良的。 

  如果編碼單元序列對應的碼點位與Unicode标量範圍之外,就是形式不良的。 

  UTF-8對起始位元組和後續位元組的位元組範圍有嚴格的限制。違反這些限制,将使生成的編碼單元序列無法映射到Unicode标量值上,産生一個形式不良的編碼單元序列。 

D30a 形式良好的(well-formed):遵照Unicode編碼格式規範的Unicode編碼單元序列,就成為形式良好的。 

D30b 形式良好的UTF-8編碼單元序列(well-formed UTF-8 code unit sequence) 

D30c 形式良好的UTF-16編碼單元序列(well-formed UTF-16 code unit sequence) 

D30d 形式良好的UTF-32編碼單元序列(well-formed UTF-32 code unit sequence) 

D30e 具有Unicode編碼格式(in a Unicode encoding form):如果一個Unicode串是由某個特定的Unicode編碼格式的形式良好的編碼單元序列組成,稱該Unicode字元串具有Unicode編碼格式。 

UTF-32 

D31 UTF-32編碼格式(UTF-32 encoding form):一種Unicode編碼格式,為每個Unicode标量值配置設定一個單一的無符号的32位編碼單元,編碼單元的數字值與Unicode标量值相同。 

  因為代理碼點沒有包括在Unicode标量值集合中,是以位與範圍0000D800到0000DFFF間的UTF-32編碼單元使形式不良的。 

  任何大于0010FFFF的UTF-32編碼單元是形式不良的。 

UTF-16 

D35 UTF-16編碼格式(UTF-16 encoding form):一種Unicode編碼格式,為處在範圍U_0000到U+D7FF和U+E000到U+FFFF内的每個Unicode标量值配置設定一個單一 的無符号的16位編碼單元,編碼單元的數字值與Unicode标量值相同;位處在範圍U+10000到U+10FFFF内的每個Unicode标量值配置設定 一個代理對。 

  因為代理碼點不是Unicode标量值,位于範圍D800到DFFF間單獨的UTF-16編碼單元是形式不良的。 

UTF-16 Bit Distribution 

Scalar Value UTF-16 

xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx 

000uuuuuxxxxxxxxxxxxxxxx 110110wwwwxxxxxx110111xxxxxxxxxx 

wwww=uuuuu-1 

UTF-8 

D36 UTF-8編碼格式(UTF-8 encoding form):一種Unicode編碼格式,位每個Unicode标量值配置設定一個由一到四個無符号位元組組成的序列。 

UTF-8 Bit Distribution 

Scalar Value 1st Byte 2nd Byte 3rd Byte 4th Byte 

00000000 0xxxxxxx 0xxxxxxx 

00000yyy yyxxxxxx 110yyyyy 10xxxxxx 

zzzzyyyy yyxxxxxx 1110zzzz 10yyyyyy 10xxxxxx 

000uuuuu zzzzyyyy yyxxxxxx 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx 

編碼格式轉換(Encoding Form Conversion) 

D37 編碼格式轉換:在一種Unicode編碼格式的編碼單元序列與另一種Unicode編碼格式的編碼單元序列間,直接定義的轉換。 

   * 在Unicode标準實作中,一個典型的API在邏輯上,将輸入的編碼單元序列轉化為Unicode标量值(碼點),然後将标量值轉化為輸出的編碼單元序列。然而,可以直接在不同編碼格式間進行轉換,以擷取更高的效率。 

   * 具有一緻性的編碼格式轉換過程應将任何形式不良的編碼單元序列作為一個錯誤條件。 

3.2.8 Unicode編碼方案(Unicode Encoding Schemes) 

D38 Unicode編碼方案:針對Unicode編碼格式的一種指定的位元組串行換,也可包括處理位元組順序标記(byte order mark, BOM)的規範。 

D39 UTF-8編碼方案(UTF-8 encoding scheme):對UTF-8編碼單元序列進行串行化的Unicode編碼方案,位元組序列與編碼單元序列本身完全一緻。 

D40 UTF-16BE編碼方案(UTF-16BE encoding scheme):将UTF-16編碼單元序列串行化為big-endian格式位元組序列的Unicode編碼方案。 

D41 UTF-16LE編碼方案(UTF-16LE encoding scheme):将UTF-16編碼單元序列串行化為little-endian格式位元組序列的Unicode編碼方案。 

D42 UTF-16編碼方案(UTF-16 encoding scheme):将UTF-16編碼單元序列串行化為big-endian或者little-endian格式位元組序列的Unicode編碼方案。 

  在UTF-16編碼方案中,與U+FEFF對應的初始位元組序列,被解釋為位元組順序标記(BOM),用于區分兩種位元組順序。初始位元組順序表明是big-endian順序,表明是little-endian順序。BOM不是文本内容的一部分。 

  UTF-16編碼方案可能以BOM開始,也可能沒有。然而,如果沒有BOM,也沒有高層協定訓示,UTF-16編碼方案的位元組順序為big-endian。 

D43 UTF-32BE編碼方案(UTF-32BE encoding scheme):将UTF-32編碼單元序列串行化為big-endian格式位元組序列的Unicode編碼方案。 

D44 UTF-32LE編碼方案(UTF-16LE encoding scheme):将UTF-32編碼單元序列串行化為little-endian格式位元組序列的Unicode編碼方案。 

D45 UTF-32編碼方案(UTF-32 encoding scheme):将UTF-32編碼單元序列串行化為big-endian或者little-endian格式位元組序列的Unicode編碼方案。 

  在UTF-32編碼方案中,與U+FEFF對應的初始位元組序列,被解釋為位元組順序标記(BOM),用于區分兩種位元組順序。初始位元組順序<00 00 FE FF>表明是big-endian順序,表明是little-endian順序。BOM不是文本内容的一部分。 

  UTF-32編碼方案可能以BOM開始,也可能沒有。然而,如果沒有BOM,也沒有高層協定訓示,UTF-16編碼方案的位元組順序為big-endian。 

3.2.9規範排序行為(Canonical Ordering Behavior) 

用于對組合字元序列提供無歧義的解釋,以便能按照可預知的方式建立和交換包含組合字元的序列。正規化是規範排序行為的另一個重要應用。 

在Unicode标準中,組合字元序列中字元的順序按照以下原則解釋: 

  所有組合字元必須跟在所應用的基字元後面。 

  封閉的标記(enclosing mark)将包圍基字元以及标記之前的所有組合字元。也包圍它之前的其他封閉标記。 

  double diacritic的結合程度比其他非間距标記(nonspacing mark)要松。當顯示時,double diacritic的位置在其他變音符之上,不包括封閉的變音符。 

  具有相同組合類别(combining class)的組合标記在書寫上的位置一般是由所修飾的基字元向外排列。一些特定的非間距标記将改變卻省的排列行為,與相鄰的非間距标記并行排列。當并行排列時,編碼的順序與書寫中占支配的順序有關。 

  如果組合字元的組合類别不同,将不會有顯示形式或語義上的差别。 

(1)組合類别(Combining Class) 

D46 組合類别:配置設定給每個Unicode組合字元的數字值,用于确定與那些組合字元在排字上互相作用。 

  如果組合字元間在排字上互相作用,則具有相同的組合類别;否則,具有不同類别。 

  封閉字元和間距組合字元的組合類别與它們的基字元相同。 

  組合類别具有的特定數字沒有特别的重要性,隻是用來比較是否相等,區分不同的組合類别。 

(2)規範排序(Canonical Ordering) 

對一個被分解的字元序列的規範排序,是根據組合類别對每個組合字元序列進行排序來完成的。字元序列的規範排序不反映任何語言正确性或偏好。 

對被分解的字元序列D進行規範排序的算法為: 

R1 對D中的任意字元x,定義p(x)為字元x的組合類别。 

R2 如果在D中存在想的字元對(A,B),并且p(B)不為零,p(A)>p(B),則交換兩個字元。 

R3 重複執行R2,直到在D中沒有發生任何交換。 

(3)Conjoining Jamo Behavior 

在Unicode标準中包含了一套預組合的Hangual音節,以及一套用于表示古老的韓文音節和現代韓文音節的jamo。 

4. 實作指南 

4.1 編碼轉換(Transcoding to Other Standards) 

一般,在Unicode标準和其他編碼标準間的映射需要通過表(table)來完成,而不是算法轉換。使用表查找常常具有比簡單算法轉換更高的效率。 

(1)多級表(Multistage Tables) 

轉 換表需要空間。即使是很小的字元集也經常會映射到Unicode标準中幾個不同的區塊中,是以,至少在一個轉換方向上(從Unicode标準到其他編碼标 準或相反),可能會包含多至64K個項(針對BMP)或1,088K個項(針對全部編碼空間)。有多個方法用于減少映射表的記憶體空間需求,這些方法不僅可 用于轉換表,也可用于其他實作Unicode标準的表結構,包括字元屬性資料、case映射等等。 

(2)Flat Tables 

如果磁盤空間不是問題,虛拟記憶體體系可以為flat table安排可接受大小的工作集,因為各字元的使用頻率有很大不同,即使是小字元集也包含一些不常使用的字元。并且,需要轉換為給定字元集的資料中的字元一般不會來自Unicode标準中的所有區塊。 

(3)Ranges 

提 供一個精心建立的嵌套範圍判斷對表進行優化,可能比較吸引人。但由于分支損失,這種方法會對現代的高度流水線式的處理器體系造成不必要的性能耗費。一種快 速的解決方案是采用優化的兩級表,可以在編碼中不包含任何測試或分支指令。盡管哈希表的速度不如多級表,但也可用于空間優化。 

(4)兩級表(Two-Stage Tables) 

兩 級表示常用的一種減少表的大小的機制。兩級表使用一個指針和卻省值的數組。如果指針為空NULL,查找傳回卻省值。否則,指針指向用于第二級查找的數值 塊。對于BMP字元,按照高位元組和低位元組值來組織這樣的兩級表非常有效,第一級是由256個指針組成數組,每個第二集區塊中包含256個值。對于增補字 符,應采取不同的方法構造指針和二級數組,以便充分考慮增補字元在剩餘編碼空間中稀疏的散布。 

(5)優化的兩級表(Optimized Two-Stage Table) 

當 任何區塊相同時,對應的指針隻需其中一個區塊。對編碼轉換表而言,這種情況一般出現在當區塊中的字元僅僅映射到"卻省"或"無法比對"的字元時。不是使用 空指針NULL和一個卻省值,而是建立了一個卻省項的"共享"塊。由于避免使用測試和分支,這種政策可以提供接近于簡單數租通路的速度,卻大大節省了存儲 空間。 

(6)多級表調節(Multistage Table Tuning) 

給定一個具有任意大小和内容的表,可以較容易的建立一個小的應用程式,來計算多級表的最佳級數和它們的寬度。通過調節級數和它們的索引指針數組的寬度,可以在表大小和平均通路時間之間進行折衷。 

4.2 ANSI/ISO C wchar_t 

在ANSI/ISO C中,為固定寬度的寬字元定義了類型wchar_t,ANSI/ISO C将寬字元集語義的定義留給了特定的實作。 

wchar_t的寬度是由編譯器指明的,可以隻有8位大小。是以,需要在不同C或C++編譯器間可移植的程式不應該使用wchar_t存儲Unicode文本。 

對 于UTF-16的實作,可以使用宏macro或者類型定義typedef(如UNICHAR),編譯為unsigned short或者wchar_t(依賴于目标編譯器和平台)。對UTF-32的實作可以使用編譯為unsigned int或wchar_t的宏或者是類型定義。這樣的選擇使在不同的系統平台和編譯其中可以正确編譯。 

4.3 未知和缺少的字元(Unknown and Missing Characters) 

4.3.1 保留的和私用的字元編碼(Reserved and Private-Use Character Codes) 

有兩類碼點,即使是完全的Unicode标準實作也無法正确解釋: 

  被保留的碼點; 

  在私用區中的碼點。 

一個實作不應試圖去解釋這樣的碼點。然而,在實際中,應用程式必須處理為配置設定的碼點或私用字元。例如,當應用程式所處理的文本是由一個實作更新版本的Unicode标準的系統建立的,其中包含更多的配置設定字元。 

對未知字元顯示的選擇包括将碼點顯示為四到六位十六進制數字,顯示一個黑得或白的方塊,針對保留字元和私用字元分别顯示适合的字形,或者什麼都不顯示。一個實作不能删除這樣的字元,也不能無目的地轉換為其他字元。 

4.3.2可解釋但無法顯示的字元(Interpretable but Unrenderable Character) 

一個實作可能接收一個配置設定給Unicode字元的碼點,但無法顯示它,因為沒有字型或者無法正确顯示。 

在這種情況下,實作可能會對使用者的詢問提供進一步有限的回報,如對資料進行适當的排序,顯示它的書寫系統,或者以卻省放時顯示碼點。對無法顯示的(但是已配置設定的)碼點和未配置設定的碼點,實作可以通過為無法顯示的碼點使用訓示類别的不同字形表示。 

4.3.3卻省的屬性值(Default Property Value) 

要使實作可以正常工作,需要把未配置設定的碼點看作字元配置設定卻省的屬性值,因為各種算法都需要配置設定給每個碼點的屬性值來運作。這些卻省值不是對所有未配置設定的碼點都相同,因為碼點中的某些範圍需要不同的屬性值以便與将來期望的配置設定做到最大相容。 

除非被特指,卻省屬性值不是标準的,具有一緻性的實作可以使用其他值。例如,取代卻省值,實作可能使用以下規則,為一塊未配置設定字元插入相鄰已配置設定字元的屬性值。 

  注意在兩個方向上最接近的已配置設定字元,如果它們處在相同的塊中具有相同的屬性值,則使用這些值。 

  從任一區塊的邊界開始,一直擴充到塊内最近的已配置設定字元處為止,使用區塊中字元對應的屬性值。 

  如果所有的碼點完全位于空的或未配置設定的塊中,使用對應屬性的卻省值。 

4.3.4卻省的可忽略的碼點(Default Ignorable Code Points) 

一 般,在可支援字元集外的碼點使用一個應變的字形顯示,如一個黑方塊。然而,格式和控制字元不應該由可見的字形(盡管它們對其他字元的顯示有影響)。除非對 于一些特定的處理,這些字元也被忽略,例如,字元ZERO WIDTH NON-JOINER在對照(collation)中忽略。為在不同版本的标準間保證最大程度的相容性,範圍U+2060到U+206F,U+FFF0到 U+FFFB,和U+E0000到U+E0FFF保留給格式和控制字元。在這些範圍中的位配置設定碼點應該在處理和顯示中被忽略。 

4.4 處理UTF-16中的代理對(Handling Surrogate Pairs in UTF-16) 

在形式良好的UTF-16中,在一個低代理碼點之前隻能是一個高代理碼點,而不能是另一個低代理碼點、一個非代理碼點或者是文本的開頭。一個高代理碼點的後面也隻能跟一個低代理碼點,而不能是另一個高代理碼點、一個非代理碼點或者是文本的結尾。 

高代理碼點和低代理碼點被配置設定了不相交的編碼單元,非代理的碼點也不會使用這些範圍内的編碼單元值表示。是以,在形式良好的UTF-16中的每個編碼單元必須隻滿足下面三個可能的條件之一: 

  一個單一的非代理編碼單元表示的碼點範圍是0到D7FF或E000到FFFF; 

  一個高代理碼點表示代理對的第一部分; 

  一個低代理碼點表示代理對的第二部分。 

最多通路兩個編碼單元,使用UTF-16編碼格式的處理過程就可以解釋任何Unicode字元。确定字元邊界最多隻需要掃描前一個或後一個編碼單元,而不需考慮其他部分。 

隻要實作不去除代理對中的任一編碼單元,或者在代理對中兩個編碼單元間錯誤的插入另一個字元,就可以保證資料的完整性。而且,即便資料被破壞了,錯誤也是局部的。 

UTF-16具有非常有利的頻率分布,在所有文本資料中的大多數部分中,代理對非常罕見,非代理碼點将非常普遍。這不僅有利于減少由于處理變長編碼而帶來的性能損失,也允許一些處理過程可以不對代理對采取特别的操作,或者使用已有處理字元序列的機制來處理代理對。 

實作必須在處理UTF-16文本時完全支援代理對。但是,實作中的單獨的元件可以具有對代理對不同程度的支援,隻要這些元件之間可以正确的組合和交流。對代理對不同程度的支援由兩個主要方面決定: 

  實作是否解釋增補的字元? 

  實作是否保證代理對的完整性? 

Surrogate Support Levels 

Support Level Interpretation Interity of Pairs 

None No supplementary characters Does not guarantee 

Transparent No supplementary characters Guarantees 

Weak Some supplementary characters Does not guarantee 

Strong Some supplementary characters Guarantees 

不支援代理對,實作就不會對任何增補字元進行解釋,也不保證代理對的完整性。 

透 明的代理對支援(transparent surrogate support),用于這樣的元件,如編碼格式轉換,它可能完全保證對代理對的正确處理,但不解釋任何增補字元。也适用于低層串處理操作的元件,一個 Unicode串隻是簡單地作為編碼單元的數組而不顧它們的代理狀态,不對串進行解釋。 

不充分的代理支援(weak surrogate support)隻正确地處理那些對應可解釋字元的代理對,可能調用的元件被保證不會傳遞無法解釋的字元。 

支援代理對的政策(Strategies for Surrogate Pair Support) 

    處理Unicode标準中進階特性的一些實作可以很容易地被改進,來支援UTF-16的代理對。例如: 

  在文本對照(text collation)中可以把代理對作為"組合字元"來處理。 

  文本的輸入可以使用一次按鍵産生兩個Unicode碼點的鍵盤來完成,就如一次ENTRE鍵可以生成CRLF或者在阿拉伯鍵盤上的"lam-alef"可以生成兩個字元lam和alef的序列。 

  文本截斷(truncation)可以使用與保證組合标記緊跟基字元相同的機制。 

如 果文本編輯器可以保證插入點(insertion point)位于字元邊界,就可以阻止使用者破壞文本。隻要使用文本元素邊界,低層的串處理程式(如wcschr)就不用進行修改。實際上,隻有某些高層的 處理需要注意代理對;底層的例程可以繼續使用對16位編碼單元操作,而不需特别對待代理對。 

4.5 處理數字(Handling Number) 

在Unicode 中,有一些字元集合用于表示不同書寫系統中的十進制數字。在數字上,解釋這些字元的系統必須提供正确的數字值。比如,在數字上,對序列解釋,具有值20。 

當從二進制的數字值轉換為可視的形式時,可以從不同的書寫系統中選擇數字。 

ASCII數字的全角變形(fullwidth)僅是通常數字的相容變形,應作為一般的西文數字對待。 

羅馬數字和東亞的表意字元數字也是十進制的數字書寫體系,但它們在形式上不是以10為基數的數字系統。是以,不可能采用一對一的方式轉換成像123456.789的形式。 

使用表意字元,也可能以兩種方法書寫數字。如數字1,234可以表示為"一千二百三十四"或"一二三四"。在數字解析使支援這些數字意味着實作必須能區分這兩種情況。 

有時候數字需要解析,但它們并不是數的一部分。例如由字母和數字組成的标示符。 

隻有在另一層上(如實作一個完整的數學公式解析器),對上标(superscripting)的解釋才是至關重要的。 

4.6 正規化(Normalization) 

(1)可選擇的拼寫(Alternative Spelling) 

在Unicode标準中對最常用的一些加重音符的字元配置設定明确的編碼。這些字元也可以通過組合獲得,對于加重音符的字母,可以由基字元和非間距标記(nonspacing mark)組合而來。 

Unicode标準提供對可由基字元加一個或多個非間距标記組合而來字元的分解。分解映射與特定Unicode标準的版本有關。 

(2)正規化(Normalization) 

系統可能會将Unicode編碼格式的文本正規化為特定的序列,如将組合字元序列正規化為由預組合字元的序列,或者相反。 

無法處理非間距标記的系統,可以正規化為預組合字元,适用于大多數基于拉丁語的現代語言。對于無法處理的組合字元,系統可以使用替代顯示方法,至少在顯示上表示組合。 

對可以處理非間距标記的系統,執行正規化消除預組合字元可能會有用,使系統對組合字元有統一的表示,保持對這類字元處理的一緻性。 

4.7 壓縮(Compression) 

    使用Unicode字元編碼可能會增加用于儲存檔案文本部分的存儲和記憶體空間。是以,對Unicode檔案或串進行壓縮是一個很好的選擇。壓縮往往建立一個更高層的協定,并且依賴于所使用的壓縮方法的知識進行交換。 

4.8 換行的原則(Newline Guidelines) 

換 行符在不同的平台上表示為:carriage return(CR)、line feed(LF)、CRLF,或next line(NEL)。不僅換行符使用不同的字元表示,并且在相同平台上,它們也具有不明确的行為。當轉換字元集編碼時,這些字元通常被直接轉換為對應的 Unicode碼點。這意味着,即使是處理純Unicode文本的程式也必須解決這些問題。特别是随着Web的出現,在一台機子上的文本可能具有不同的來 源,将引起很大問題。 

換行符用來明确訓示行的邊界。 

4.8.1 定義(Definitions) 

Hex Values for Acronyms 

Acronym Name Unicode ASCII 

CR carriage return 000D 0D 

LF line feed 000A 0A 

CRLF carriage return and line feed 000D,000A 0D,0A 

NEL next line 0085 85 

VT vertical tab 000B 0B 

FF form feed 000C 0C 

LS line separator 2028 n/a 

PS paragraph separator 2029 n/a 

在Unicode标準中,沒有正式地配置設定控制字元,而是為各種7位和8位字元編碼标準中使用控制字元提供相應的碼點。確定了Unicode标準與其他編碼标準的相關性和互相映射。 

縮寫NLF(newline function)表示針對一個新行分隔符的一般控制功能。 

4.8.2 背景(Background) 

段落分隔符(paragraph separator)用于訓示段落之間的分隔。行分隔符(line separator)訓示在何處進行斷行,特别是在一個段落中。 

記錄分隔符(record separator)用于分隔記錄。例如,當交換表格式資料時,一種普通的格式是使用TAB分隔單元和在一行單元後使用CRLF。盡管這種功能與行分隔不是正好相同,但使用了同樣的字元。 

NLF開始時作為行分隔符。現在,在一些簡單的文本編輯器中還作為行的分隔符。随着平台和程式開始使用自動分行進行字處理,這些字元被用于表示段落分隔符。 

一旦NLF被用來表示段落分隔符,在一些情況下,另一個控制字元就被作為行分隔符使用。例如,在Microsoft Word中,就使用vertical tabulation(VT)。 

4.8.3 建議(Recommendation) 

在Unicode 中,定義了兩個明确的分隔字元:U+2029 PARAGRAPH SEPARATOR(PS)和U+2028 LINE SEPARATOR(LS)。在Unicode文本中,應該在所表達功能明确的地方使用PS和LS字元。否則,當從其他字元集轉換為Unicode時,當 解釋文本中的字元時,和當從Unicode轉換為其他字元集時,使用以下規則處理NLF。 

即使實作知道在一個特定的平台上用哪個字元表示NLF,在輸入和解釋時CR、LF、CRLF和NEL應該被相同對待。隻要在輸出時,才有必要進行區分。 

(1)從其他字元編碼集轉換 

R1 如果知道NLF的确切的用法,則轉換為LS或PS。 

R1a 如果不知道NLF的确切用法,則映射為與平台對應的NFL。 

(2)解釋文本中的字元 

R2 總把PS解釋為段落間隔,把LS解釋為行間隔。 

R2a 在字進行中,把任一NLF都解釋為PS。 

R2b 在簡單文本編輯中,把任一NLF都解釋為LS。 

R2c 在解析中選擇最安全的解釋。 

例如,對R2c,涉及斷句啟發規則的實作會按照以下方法,将NLF安全的解釋為LS: 

  當一個NLF應是PS時,假設把它解釋為LS。因為多數段落總是以标點符号結束,這隻會在個别情況造成對句子邊界的錯誤識别。 

  當一個NLF應是LS時,假設把它解釋為PS。在這種情況下,行分隔符将是句子斷開,對斷句啟發規則帶來很大錯誤。 

(3)轉換為其他字元編碼集 

R3 如果已知轉換的目标,根據目标協定,适當地對NLF、LS和PS進行映射。 

例如,當映射為Microsoft Word對文檔的内部協定時,LS将映射為VT,PS和其他NLF将映射為CRLF。 

R3a 如果不知道轉換的目标,将NLF、LS和PS映射到平台的換行協定。 

(4)輸入和輸出 

R4 函數readline應該在遇到NLF、LS、FF或PS時停止。在典型的實作中,不包括停止位置的NLF、LS、FF或PS。 

因為分隔符會丢失,對這種readline函數的使用僅限于與分隔符的類型無關的文本處理。 

R4a 函數writeline應該根據(3)中的協定轉換NLF、LS和PS。 

(5)頁面分隔符 

FF一般用作頁面分隔符,在文本中應該按照情況解釋。當在螢幕上顯示時,在分隔符後的文本會被強制放如下一頁。它與段落分隔符無關:一個段落可以在一頁開始在下一頁中繼續。除非是在頁面中顯示,在大多數解析過程和readline中,與LS的解釋相同。 

4.9 正規表達式(Regular Expressions) 

面向位元組的正規表達式工具需要擴充以正确處理Unicode。下面是擴充所涉及方面: 

  Unicode是一個很大的字元集,隻适用于處理小字元集的正規表達式工具可能無法調整。 

  Unicode包括多種語言,它們具有與英語或其他西歐語言非常不同特性。 

4.10 純文字中的語言資訊(Language Information in Plain Text) 

4.10.1 語言标記的需要 

在純文字資料中嵌入語言資訊的需要經常被誇大。一些普通操作,如對照(collation)很少需要這些額外資訊。 

然 而,語言資訊對某些操作非常有用,如對一個混合語言的文檔執行拼寫檢查或者連字(hyphenating)。對于為無格式文本選擇卻省字型也非常有用,例 如日文字型中的省略符号具有與英文字型不同的外觀。目前的字型和布局(layout)技術基于語言資訊産生不同結果。盡管語言資訊對于執行文本-語音轉換 (text-to-speech)操作有用,但目前的文本-語音轉換軟體都必須對文本執行非常複雜的文法分析,是以确定語言的額外工作就不那麼重要了。 

語言資訊可以使用帶外資訊(out-of-band)或内嵌标記(inline tag)表示。在内部實作中,通常使用帶外資訊,儲存在與文本并聯的資料結構中,而不是嵌入到文本資料中。帶外資訊不影響對文本的正常處理,還可以輕松的支援對文本的操作。 

4.10.2 語言标記與漢字統一 

對Unicode中漢字統一的一個常見誤解是覺得沒有語言資訊就無法正确顯示漢字字元。其實,漢字統一的目标和方法是確定文本可讀。盡管需要添加字型、大小、寬度和其他格式規格,以便在源和目标機器上準确産生相同的外觀,但在沒有這些規格時,純文字也能保證可讀。 

因為不同國家所使用的統一的漢字間的不同,都僅限于格式上的變化,不會引起Unicode中的混亂。在Unicode中的漢字統一不會使讀者音唯一不同的字型顯示而無法識别一個字元。如果準确的字型資訊很重要,最好使用格式文本。 

4.11 編輯和選擇(Editing and Selection) 

一緻的文本元素(Consistent Text Elements) 

從 使用者的角度,文本的基本表示不是所關心的,但重要的是,編輯接口必須對使用者所認為的字元提供一個統一的實作。使用者希望在滑鼠選擇、方向鍵移動、倒退等操作 中,這些字元表現得像一個個單元。例如,當實作這些行為後,對一個表示為基字元加非間距組合标記序列的加重音符字母,使用右移方向鍵時,邏輯上會從基字元 的開始跳到最後一個非間距字元後面。 

在詞中的編輯和選擇,一般有三種類型的邊界(boundary)。 

簇邊界(cluster boundary) 

任意定義的簇邊界可能會出現在像梵文(Devanagari)這樣的書寫系統中,選擇操作可能會應用于音節或者音節的一部分。在這種情況下,組合字元序列,如ka+vowel sign或者聯合的簇ka+halant+ta,作為單一的單元選擇。 

堆疊字元邊界(stacked boundary) 

堆疊字元邊界一般比簇邊界更細。獨立的元素(如梵文vowel sign a)可以不受限制的選擇,但是任何堆疊在一起的字元(包括垂直連字元,如阿拉伯文中的lam+meem)隻能作為單一的單元選擇。 

原子字元邊界(atomic character boundary) 

原 子字元邊界的使用最接近于單個Unicode字元的選擇。然而,大多數目前系統都采用某種矩形加亮的方式表示選擇操作。這種方法限制了編輯操作的一緻性, 因為一些字元序列不是從行的起始處成直線地發展。當字元堆疊時,兩種機制被用于對部分選擇地顯示:直線的和非直線的邊界。 

直線的邊界(linear boundary) 

使用直線邊界,将合成字形的全部寬度都歸屬于序列的第一個字元,認為其餘字元沒有寬度。 

這是最簡單的一種機制。它的優點是隻需要很少的額外實作工作。它的缺點是選擇窄字元變得非常困難,更不用說零寬度的字元。需要使用者剛好從非間距标記右邊開始選擇,并且正好拖到左邊。如果有多個非間距标記,它也不允許對單個标記進行選擇。 

非直線的邊界(nonlinear boundary) 

使用非直線邊界把任何堆疊字元分成各個部分。可以通過對多個矩形加亮,或者對單個字元着色的方法進行表示。 

注意到,通過更多的操作,一個預組合的字元在删除操作中可以表現得像一個具有原子字元邊界組合字元序列一樣。這個過程包括動态地獲得字元的分解表示,得到用作模拟的元件。 

在多數系統中,字元時文本中最小的可尋址單元,是以選擇操作和屬性配置設定操作(如字型、顔色、字元間距等)都在字元的基礎上執行。對于預組合地字元無法模拟這種可尋址性,系統地修改所有文本編輯工具來對字元的一部分進行尋址,會十分低效。 

由 于文本元素不具有一個單一的概念,是以,對字元邊界的編輯也沒有一個統一的概念。在不同情況下,使用者可能會在編輯過程中使用不同程度的粒度大小。可以考慮 兩種方法:首先,使用者可能設定對字元邊界的一個全局偏好;第二,使用者可能有可選的指令機制,如Shift-Delete,可以提供對卻省模式更細(或更 粗)的控制。 

4.12 處理非間距标記的政策 

依據一下政策,開發者可以實作對非字元間距有效和高效使用的系統和例程。開發者也可以選擇适用于絕大多數已有系統的最小限度的技術,和适用于要求更苛刻的情況的複雜技術,如高端的桌面出版。 

在 這裡,術語非間距标記(nonspacing mark)群組合字元(combining character)可以互換使用。有時會使用術語diacritic、accent、stress mark、Hebrew point、Arabic vowel等,而不是非間距标記(它們表示特定類型的非間距标記)。 

為支援非間距标記,隻需要相對較小數量的實作特性。存在多種可能層次的實作。一個最小的系統可以産生較好的結果,并且相對容易實作。要求大多數特性地系統,隻是對已有軟體地簡單修改。 

因為有一些語言要求非間距标記,如Arabic、Hebrew和印度次大陸的語言,已有一些可以處理這些字元的系統,可以利用已有經驗來生成處理Unicode标準中這些字元的多用途軟體。 

顯示(rendering) 

一 部分确定的組合字元序列可以通過簡單的替換來有效顯示。當遇到一個有基字元加一個或多個非間距組合标記組成的序列時,可以使用表示組合形式的字形進行替 換。在簡單地字元顯示中,一個非間距組合标記不增加寬度,一個組合字元序列的具有與基字元相同的寬度。當截斷串時,從結尾處開始向後執行截斷總是最容易。 後續的非間距标記将不會與前面的基字元分開。 

一個更複雜得顯示系統會考慮使用非間距标記時對寬度和字距更細微的調整,或者組合字元序列具有與基字元不同寬度。對大多數應用而言,這樣地顯示系統并不是必需的。 

其他處理:正确的多語言比較例程也必須能夠把字元序列作為一個字元比較,或者把一個字元看作是一個字元序列。隻要提供了适當的資料,這些例程也能處理組合字元序列。當查詢串時,要檢查目标串中可能會影響最後一個比對字元解釋的附加非間距标記。 

斷行算法一般使用狀态機,确定詞間的中斷。這樣的算法可以很容易地改進,來阻止将非間距标記從基字元分開。 

鍵盤輸入(Keyboard Input) 

用 于組合字元序列輸入的一個常見實作,是使用所謂的dead key。這些鍵與打字機生成這樣序列所使用的機制比對,通過在非間距标記之後鍵入基字元。在計算機的實作中,當按下針對重音符的dead key時鍵盤進入一種特殊的狀态,隻有當鍵入一些有限數目的"合法"基字元之一時産生一個預組合的字元。根據需要,可以改進系統來生成組合字元序列或者預 組合的字元。盡管打字員,特别是使用Latin書寫系統的,是針對這類系統教育訓練的,然而在Unicode标準中一些書寫系統(包括Latin)可能會依據 書寫的順序來實作,使用者首先鍵入基字元,其後跟着重音符或其他非間距标記。 

在書寫順序的情況下,每一次鍵入都在螢幕上産生一個不同的自然變化。要給已有的字元添加重音符,使用者需要把插入點移到字元後在鍵入重音符。 

截斷(Truncation) 

有兩種類型的階段:根據字元數目截斷和根據顯示寬度截斷。根據字元數目截斷可能帶來資料損失,也可以是無損失的。 

根據字元數目進行截斷使用在,由于存儲限制,隻有有限數目的字元可以放入某區域;也用于,為了傳送和其他目的将文本插入緩沖區中。在後一種情況下,如果在處理前緩沖區中的資料可以無縫的重新組合,或者預先檢查一下可能出現的跨緩沖區組合字元序列,就可以做到不丢失資料。 

當調整資料以适應有現長度的區域時,一些資訊将會丢失。在文本邊界上進行截斷(例如,在組合字元序列的最後或者在最後一個詞邊界)通常比在最後一個碼點後截斷更可取。 

根據顯示寬度截取用于有限範圍内的可視顯示。在這種情況下,截斷是依據結果串的寬度而不是字元的數目。在簡單的系統中,依據寬度截斷很容易,從末尾處開始向後操作減去字元的寬度。由于後續非間距标記對串的尺寸沒有貢獻,最後結果不會把非間距标記與它們的基字元分開。 

如果文本環境會更複雜,字元的寬度可能會依賴上下文環境,由于字元間距調整、連字或上下文資訊等的作用。對這種系統,一個組合字元的寬度可能會與一個單獨的窄字元(如i)的寬度不同。處理這種情況,必須對截斷結果進行核查。 

一個不同的選擇是在圖形上對字元進行修剪。但不幸的是,結果可能很難看。并且,如果修剪出現在字元之間,可能不會給出任何世界回報表示字元被删除了。 

4.13 非間距标記的顯示(Rendering Nonspacing Marks) 

在這裡假定使用均衡字型(proportional font),單個字元的寬度可以變化。對于等寬字型(monospaced font),可以使用各種技術,但一般而言,對于這種字型的多數書寫系統,可能隻有一種正确的顯示外觀。 

當 顯示的序列中包含多于一個的非間距标記時,卻省情況下,非間距标記從基字元向外堆疊。即,如果亮格非間距标記出現在基字元的之上,則第一個非間距标記位于 基字元上面,第二個非間距标記為與第一個标記上面。如果亮格非間距标記出現在基字元的之下,則第一個非間距标記位于基字元下面,第二個非間距标記為與第一 個标記下面。 

這種卻省行為可能會根據排字上的偏好,或者某個特定書寫系統中對多個非間距标記的特定正字法處理,而改變。 

後退的顯示(fallback rendering) 

有幾個方法可用于處理在一個固定的可顯示集合外未知的組合字元序列。 

一種方法是Show Hidden,通過先顯示基字元再把非間距标記作為單個單元顯示,來表示無法描繪序列。 

另一種方法是Simple Overlap,将重疊的零寬度非間距标記放置在卻省的固定位置處,一般所放置的位置例可能的基字元較遠。盡管顯示結果對于一些字母而言沒有吸引力,但在隻有一個非間距标記的情況下,結果一般還是可以辨認的。 

在一個退化的情況下,一個非間距标記作為文本的首字元出現,或者被行分隔符、段落分隔符或其他引起位置分隔的格式符從它的基字元分開。這種結果稱為不良的組合字元序列。不良的組合字元序列在顯示時,看作是以一個空格作為基字元。 

雙向定位(bidirectional positioning) 

在雙向文本中,非間距标記與它們的基字元一起重新排序。即視覺上,在使用雙向算法之後它們應用于相同的基字元。 

調整(justification) 

典型地,對文本的完全調整要給間距字元(space character)添加額外的空間;然而,如果隻有很少(或沒有)間距字元,一些系統會在字元間添加額外的字間隔空(letterspacing)。如果在文本中包含零寬度的非間距标記,則需要對該過程進行改進。 

因為非間距标記總是跟随它們的基字元,正确的調整過程應該隻有當第二個字元是一個基字元時才會在字元見添加字間隔空。 

規範等價性(Canonical Equivalence) 

在 顯示多個重音符時,必須考慮規範等價性,以便使任兩個規範等價的序列顯示結果相同。這一點在當規範順序與習慣的鍵盤輸入順序不相同時特别重要,如具有元音 符号的阿拉伯文和使用點的希伯萊文。在這些情況下,顯示系統得到的是典型的鍵入順序或者是經過正規化(normalization)的規範順序。 

顯示系統應該處理組合标記的任何具有規範等價性的序列。這不會有性能問題,因為對組合标記重新排序所需的時間與其他顯示工作的耗時相比微不足道。 

一個顯示系統,在需要時,可以在内部對标記重新排序,隻要結果序列是規範等價的。 

定位方法(Positioning Methods) 

有一些方法可用于定位非間距标記,使它們相對于基字元和前一個非間距标記(如果有的話)的位置正确。 

使用連字(positioning with Ligature) 

一 個固定範圍的組合字元序列可以使用相對簡單的替換來有效顯示。當字形可以表示一個序列<基字元,非間距标記>時,使用這個字形替換組合形式。 因為非間距标記的擴充寬度為零,組合字元序列将自動具有與基字元相同的寬度。跟複雜的文本顯示系統可能會采取進一步的措施來處理一些特殊情況,如組合字元 序列的緊排(kern)或者寬度與基字元不同。 

使用連字可能是支援非間距标記最簡單的方法。對于較小的固定字集,如那些對應ISO/IEC 8859-1(Latin-1)重預組合字元的,可以直接采用該方法。因為組合字元序列幾乎總是具有與基字元相同的寬度,對這些字元的顯示、測量和編輯與 一般連字的情況相比都更容易。 

如果組合字元序列不能形成一個連字,就需要采用以下兩種方法之一。如果這些方法都不可用,則使用後退的方法。 

根據上下文結構定位(positioning with contextual forms) 

處理非間距标記定位的一個較通用的方法是使用上下文的結構。在這種情況下,有幾個不同的字形對應于重音符的不同位置。依據大緻的形狀和寬度,基字形(基字元的字形?)通常分成數目較小的一些類别。根據基字形的類别,為非間距标記選擇一個特定的字形。 

在一般情況下,可以從一些具有不同高度的字形中進行選擇,以便堆疊字形。這種方法可以與使用連字的方法結合使用,就可在特定情況下,使用連字生成更高的變形。 

使用增強的字距調整(positioning with enhanced kerning) 

第三種用于定位讀音符号的技術是對正常的字距調整(水準的和垂直的)的擴充。典型地,字距調整過程唯一對字形映射一個位置偏移量。例如,在詞語"To"中,"o"應該向"T"下面靠一點。這種系統的擴充則分别映射一個垂直的和水準的偏移量。 

為了針對一般情況可以有效應用,字距調整過程也必須能夠處理比簡單字元對更複雜的情況,如在一個基字元後可能有多個讀音符号。 

使用增強的字句調整技術進行定位,也可以和使用連字的方法結合運用。 

4.14 定位文本元素邊界(Locating Text Element Boundaries) 

Unicode 編碼的文本串經常需要被分解為文本元素。文本元素的一般例子包括字元、詞、行和句子。文本元素的準确确定可能會依據地區而變化。但要與使用者的了解相比對并 不是總能達到的,因為文本本身并不總是包含足夠的資訊用于明确決定邊界。例如,句點"."(U+002E FULL STOP)的使用具有歧義,有使用于表示句子結束,有時用于縮寫,有時則用于數字。然而,在多數情況下,文本邊界可以符合使用者的了解。 

4.15 辨別符(Identifiers) 

Unicode 标準的實作面臨的一個常見任務是提供針對辨別符的解析工具。為了促進在基于Unicode字元的解析器中對辨別符的标準化處理,這裡針對辨別符文法的定義 提出一套指導方針。這些指導方針并不比普通程式設計語言中規則更複雜,隻不過包含了更多具有不同類型的字元。 

基于屬性的辨別符文法(property-based identifier syntax) 

這 裡提供的正式文法就是要明确,一個辨別符是由一個字母或者一個表意字元開始,包含任意數目的字母、表意字元、數字或下劃線的字元串組成的。每種程式設計語 言标準都有自己的辨別符文法,不同程式設計語言對ASCII範圍内特定字元的使用有不同的約定。對這些文法進行擴充以具備Unicode實作的全部行為, 隻需要講這些特定規則與下面提供的樣本文法結合。 

為了正确的涵蓋Unicode标準,樣本辨別符文法中的革新之處包括: 

  結合對組合标記的恰當處理。 

  允許有布局和格式控制字元,在解析辨別符時忽略。 

組合标記(combining marks) 

辨別符文法中必須考慮組合标記。由一個基字元跟随若幹組合标記組成組合字元序列對一個辨別符而言是有效的。 

封閉的組合标記被排除在的文法定義外,因為由它們和字母所組合得到的組合字元不是這些辨別符有效的組成部分。 

布局和格式控制字元(layout and format control character) 

用 于控制組合行為,雙向順序控制和可選顯示格式的Unicode字元,被明确定義為不影響中斷行為。不像空格符或其他分隔符,它們不用來訓示詞、行或其他單 元的邊界。因而,為了辨別符定義,将它們明确包括在内。一些實作可能選擇過濾掉這些可忽略字元,這種方法的優點在于兩個顯示相同的辨別符更可能是相同的。 

特殊字元調整(specific character adjustments) 

特殊的辨別符文法可以被看作是基于字元屬性對普通文法的少量修改。例如, SQL辨別符允許下劃線作為辨別符的一部分(但不能作為開始字元);而C辨別符允許既下劃線作為辨別符的一部分也可以作為辨別符的開始字元。 

可以考慮排除在辨別符外的字元集合包括所有相容映射具有标記的字元。 

文法規則(Synactic Rule) 

:= (| 

)* 

Sytactic Classes for Identifiers

Syntactic Class Properties 

General Category = L or Nl, or 

Other_ID_Start = true 

General Category = Mn, Mc, or Nd, Pc, or Cf 

可選建議(Alternative Recommendation) 

使用文法類别不足之處是,用于詳細定義的存儲空間,以及随着新版本Unicode标準添加的新字元無法被已有的解析器識别。也就是說,無法做到向上相容。 

解決該問題的一個方法是,不去定義允許使用的碼點集合,而是将一個較小的固定的碼點集合保留給文法使用并且允許使用其他任何碼點(包括非配置設定的碼點)用作辨別符的一部分。按照這種規範編寫的解析器對任何版本的Unicode标準得表現相同。 

這種方法的缺點是辨別符中部分可能是沒有意義的東西,因為将詞彙分類與人類的可了解性分開了。然而,可了解性可以通過其他方法解決,如使用用法指南限定使用有意義的術語。例如W3C指定的規範XML 1.1。 

通 過增加不允許使用字元的集合,可以得到針對辨別符較直覺的建議。這種方法使用Unicode标準一個特定版本中關于辨別符類别的所有規範,并且永遠不允許 使用該版本中不推薦用作辨別符的字元。該版本Unicode标準中沒有配置設定的所有碼點可用于辨別符,已經考慮到将來對版本的添加。這種方法保證了向上相容 的辨別符穩定性,以及将字元合理地劃分為具有或不具有意義的辨別符組成。 

可以對禁止使用的碼點清單進行一些額外的擴充,來進一步限制不合理的辨別符。 

4.16 排序和查找 

排 序和查找操作部分相一緻,都要實作互相比較項的等價程度判定。在查找操作中,等價定義項是否比對;在排序操作中,等價影響項在有序隊列中的鄰近。等價的确 定經常依賴于應用和語言,但對于支援Unicode标準的實作而言,排序和查找必須考慮到Unicode字元的等價性和規範順序。 

與語言文化有關的排序和查找 

排 序順序随着文化的不同而變化,并且一些特殊的應用需要變化。排序的順序可以依據詞或者句子,區分大小寫或者不分大小寫,忽略重音符或者不忽略;也可以是依 據語音,或者基于字元的外觀,比如使用筆劃和部首對東亞的表意字元排序。對漢字的語音排序需要使用詞語的查找詞典,或者是可以維持文本中詞和相關語音拼寫 的特殊程式。 

語言不僅決定使用哪一種排序,而且決定什麼構成排序的基本元素。例如,瑞典語中将U+00C4 LATINE CAPITAL LETTER A WITH DIAERESIS作為一個單獨的字母,在字母表中排在z之後;然而,在德語中,則作為ae或者識跟随在a之後的其他重音形式。西班牙語在傳統上将連字 ll看作在l和m之間的字母來排序。 

是以,不可能在編碼時以某種順序安排字元以便通過簡單的二進制串比交接可以生成期待的順序,也不可能提供單級的排序權重表。後者意味着字元編碼細節對文化上期待的排序隻具有間接的影響。 

與語言無關的排序 

在 一些環境下,應用程式可能需要進行與語言無關的排序,即對文本資料排序,而不考慮針對串如何排序的與語言相關的文化期望。例如,一個臨時的索引可能隻需要 以某些定義良好的順序排列,但排序的準确細節并不重要或者對使用者不可見。然而,即使在這種情況下,也需要注意一些問題。 

首先,三種Unicode編碼格式的二進制排序存在一些細微的差别。隻需要對Unicode串進行二進制比較的實作必須考慮這一點,不至于在使用不同編碼格式的應用程式間引起互操作問題。 

一些排序或者查找應用,即使不關心排序中與語言相關的差别,也要求與大小寫無關。傳統上,執行與大小寫無關比較的實作是通過在二進制比較前将兩個串都轉換為大寫的形式來完成的。然而,這種方法一般不能擴充到Unicode标準中的所有字元。 

查找 

查找也受比較操作中一些同樣的問題影響。也增加了其他一些特征,如隻比對詞(即在比對的兩邊都是詞的邊界)。一種技術是針對一個弱比對進行快速查找。當發現一個候選比對時,根據其他标準(如比對變音符,詞比對,大小寫比對等等)。 

當 查找串時,必須檢查目标串中尾随的非間距标記,可能影響最後一個比對字元的解釋。也就是,查找"San Jose"可能會在串"Visiting San José, Costa Rica is a ..."發現一個比對。如果要求準确的比對,則應該否決該比對。如果隻要求弱比對,則可以接受該比對,但是在傳回目标字串的位置和長度時必須包括尾随的非 間距标記。 

弱等價的一個重要應用是與大小寫無關的檢索。一些傳統的實作将查找串和目标串都映射為大寫。然而,大小寫映射是依賴語言的,并且不是沒有歧義。 

因為從外部字元集的錯誤映射,産生一個相關問題。為了解決這個問題,可以将使用者易搞混的字元歸為一個弱比對類。這種方法在查找命名的檔案或其他對象時可以更好的滿足使用者的語氣。 

次線性查找(Sublinear Searching) 

使用比較資訊,通過硬算(brute force),國際化的查找是可能的。然而,這種政策在最壞情況下需要O(m*n)算法,在一般情況下需要O(m)算法,n是所尋找的模式中字元的數目,m是目标串中的字元數。 

一些算法可以使用次線性的算法對簡單文本進行快速查找。通過在目标串中跳過字元,這些算法在通常情況下的複雜度隻有O(m/n)。 

在次線性查找中采用與語言有關的比較算法的主要問題,與多映射和可忽略有關。另外,次線性算法預先計算資訊表。 

4.17 二進制順序 

如果比較文本對最終使用者是可見的,就應該使用正确的語言排序。然而,在有一些情況下,隻需要一個快速的有良好定義的排序。在這種情況下,可以使用一個二進制排序。 

Unicode 中的所有編碼格式并沒有相同的二進制順序。UTF-8和UTF-32的資料以碼點順序排序,而UTF-16的資料(碼點高于U+FFFF)則不是。而且, 當UTF-16或UTF-32資料使用某個Unicode模式序列化,并以位元組比較時,得到的位元組序列可能具有也可能沒有相同的二進制排序,因為交換位元組 順序将影響資料的大體排序。由于這些因素,UTF-16BE、UTF-16LE、UTF-32LE編碼方案下的文本不是以碼點順序排序。 

一般,Unicode文本的卻省二進制排列順序應該是碼點順序。然而,可能需要與特定編碼格式中的編碼單元順序(或是特定編碼方案的位元組排序)比對,以便完成不同應用中使用的排序。 

4.18 Case Mapping 

Case 是特定字母表中字元的一個标準屬性,比如Latin、Greek、Cyrillic、Armenian,和古代格魯吉亞文,字元被認為是單個字母的變體。 這些變體在形狀和大小上可能差別很大,稱為大寫字母和小寫字母。一般大寫字母比小寫字母大。具有大小寫差異的字母表稱為bicameral;沒有的則稱為 unicameral。 

為了相容性還包含了某些組合字元,如U+01F1 "DZ" LATIN LETTER DZ,就有了第三種狀态,稱作titlecase,用于當詞的第一個字元被大寫時。這種字元的一個例子是U+01F2 "Dz" LATIN CAPITAL LETTER D WITH SMALL LETTER Z。 

是以,三種狀态形式為UPPERCASE、Titlecase和lowercase。 

術語"titlecase"可用于指詞語,它的第一個字母是一個大寫字母或者是titlecase字母,其餘字母為小寫。然而,并不是所有在文檔标題中的詞或者句子中的第一個詞都是titlecase。 

決 定哪一個詞是titlecase依賴于語言。例如"Taming of the Shrew"在英語中是适當的大寫,但"Taming Of The Shrew"不是。而且,決定什麼真正組成一個詞是與語言相關的。例如,l'arbre在法語種可能被認為是兩個詞,但can't在英語種被認為是一個 詞。 

Case Mapping的困難 

一旦字元集超出了ASCII的範圍,case mapping就會有一些困難。 

在多數情況下,titlecase與uppercase相同,但并不總是這樣。例如,U+01F1 "DZ" capital dz的titlecase是U+01F2 "Dz" capital d with small z。 

case mapping可能生成與源串的長度不同的串。例如,德文字元U+00DF LATIN SMALL LETTER SHARP S在轉換成大寫時擴張成兩個字元的序列"SS"。這種情況也出現在沒有預組合字元的情況下。 

由一些字元需要特殊的處理,如U+0345 combining iota subscript。 

依 賴上下文環境,字元也可能有不同的case mapping。例如,U+03A3 GREEK CAPITAL LETTER SIGMA,當後面跟随其他字母的時,對應的小寫字元為U+03C3 GREEK SMALL LETTER SIGMA;沒有跟其他字母時,對應小寫字元為U+03C2 GREEK SMALL LETTER FINAL SIGMAL。 

字元的case mapping可能依賴于地區。 

由于一些字母實際上不分大小寫,沒有比對的大寫形式,是以,将一個串轉換為大寫的過程并不意味着不包括任何小寫字母。 

可逆性(Reversibility) 

必須注意到,沒有case轉換操作時可逆的。例如: 

toUpperCase(toLowerCase("John Brown")) -> "JOHN BROWN" 

toLowerCase(toUpperCase("John Brown")) -> "john brown" 

甚 至還有一些單個詞,像意大利語中的vederLa或英語中的名字McGowan,既不是大寫,也不是小寫或titlecase。這種形式有時稱作 inner-caps,通常用于程式設計和Web名稱。一旦串"McGowan"被轉換成大寫、小寫或titlecase,就不可能通過另一個大寫、小寫 或titlecase操作恢複原樣。也存在單個的字元沒有可逆的映射,如希臘文中的sigma。 

對于使用單個指令鍵組成的序列在不同case間轉換所選擇内容的字處理軟體,建議儲存初始串,并且可以通過鍵序列傳回初始串。使用者界面要生成以下對一系列指令鍵響應的結果。注意,初始串每隔四次就會被存儲。 

1. The quick brown 

2. THE QUICK BROWN 

3. the quick brown 

4. The Quick Brown 

5. The quick brown 

在字處理軟體中,大寫、小寫和titlecase可以使用字元類型來表示。去除字元類型,就将文本恢複為初始狀态。然而,如果采用這種方法,任何拼寫檢查軟體必須注意case類型,以便可以對真正的外觀進行檢查。 

不分大小寫的比對(Caseless Matching) 

不分大小寫的比對是使用case folding實作的,該過程将串映射為一種消除了大小寫差異的規範形式。Case folding顧及到查找中的不分大小寫的快速比對,因為隻需要二進制比較。它不僅僅是隻轉換為小寫形式。 

通常,初始的串不會被轉換的串替代,因為這樣的替代可能會抹掉重要的資訊。例如,名字"Marco di Silva"轉換為"marco di silva",失去了關于哪個字母是大寫的資訊。 

在Unicode Character Database(UCD)中的檔案CaseFolding.txt用于執行與地區無關的case folding。該檔案是通過單字元映射和多字元映射,從UCD中的case mapping生成的。它将所有具有不同case形式的字元轉換成一個普通形式。對兩個串進行不分大小寫的比較時,可以利用這些資料對串進行轉換,在使用 二進制比較。

繼續閱讀