Normallashtirilgan UTF-8 nimani anglatadi?

ICU loyihasi (shuningdek, hozirda PHP kutubxonasi ) izlanayotgan qiymatlarni taqqoslashni osonlashtirish uchun UTF-8 satrlarini normallashtirishga yordam beradigan sinflarni o'z ichiga oladi.

Biroq, ilovalar uchun bu nimani anglatadi »ni aniqlashga harakat qilaman. Misol uchun, qaysi holatlarda "moslik ekvivalentligi" yoki "versiya" o'rniga "Canonical Equivalence" ni istayman?

116
@ObscureRobot Albatta, bu qo'shimcha ramzlar mavjud yoki yo'qligini bilishni xohlayman
qo'shib qo'ydi muallif Eonil, manba
@ObscureRobot Misol uchun, ba'zi bir kod shu kabi: kod (kodirovkali chiziq boshlang'ich) (char1) (char2) ... (charN) (chekka chiziqli tugma) ) (char1) (egri chiziq belgisi prefiksi) (char2) (egri chiziq belgisi prefiksi) (char2) . Boshqacha qilib aytganda, minimal birlik yaratilishi mumkin?
qo'shib qo'ydi muallif Eonil, manba
Bu o'z-o'zidan yaxshi savolga o'xshaydi.
qo'shib qo'ydi muallif ObscureRobot, manba
@Eonil - Unikode kontekstida qaysi davlat nimani anglatishini bilmayman.
qo'shib qo'ydi muallif ObscureRobot, manba
Kim ̸͢k̵͟n̴͘ǫw̸̛s͘ w͘͢ḩ̵a҉̡͢t dahshatlarini yolg'on The Dark yurak Unicode? ͞
qo'shib qo'ydi muallif ObscureRobot, manba

7 javoblar

Unicode Normalizatsiyasi haqida bilishni xohlamagan har bir narsa

Kanonik normallashtirish

Unicode includes multiple ways to encode some characters, most notably accented characters. Kanonik normallashtirish changes the code points into a canonical encoding form. The resulting code points should appear identical to the original ones barring any bugs in the fonts or rendering engine.

Qachon foydalanish

Because the results appear identical, it is always safe to apply Kanonik normallashtirish to a string before storing or displaying it, as long as you can tolerate the result not being bit for bit identical to the input.

Kanonik normallashtirish comes in 2 forms: NFD and NFC. The two are equivalent in the sense that one can convert between these two forms without loss. Comparing two strings under NFC will always give the same result as comparing them under NFD.

NFD

NFD belgilar to'liq kengayib boradi. Bu hisoblash uchun tezroq normallashtirish shaklidir, lekin natijalar ko'proq kod nuqtalarida (ya'ni ko'proq joy ishlatiladi).

Faqat normalizatsiya qilinmagan ikkita satrni solishtirishni istasangiz, moslik normallashuviga muhtoj ekaningizni bilmasangiz, bu holat normalizatsiya shaklidir.

NFC

NFC NFD algoritmini ishga tushirgandan so'ng imkon qadar kod nuqtalarini birlashtiradi. Bu bir oz ko'proq vaqt oladi, ammo qisqaroq satrlarga olib keladi.

Muvofiqlikni tartibga solish

Unicode-da, aslida tegishli emas, balki eski belgilar majmualarida ishlatilgan ko'pgina belgilar mavjud. Unicode, bu belgilar majmui ichida Unicode sifatida ishlashga ruxsat berish uchun ularni qo'shib qo'ydi va keyin yo'qotishsiz qayta aylantirildi.

Muvofiqlikni tartibga solish converts these to the corresponding sequence of "real" characters, and also performs Kanonik normallashtirish. The results of Muvofiqlikni tartibga solish may not appear identical to the originals.

Formatlash ma'lumotlarini o'z ichiga olgan belgilar o'zgartirilmagan narsalar bilan almashtiriladi. Masalan, belgisi 9 ga o'zgartiriladi. Boshqalari formatlashma farqiga ega emas. Misol uchun, roman kodi belgisi oddiy kodlarga aylanadi. IX .

Shubhasiz, bu o'zgarish amalga oshirilgandan so'ng, endi yo'qolib qolgan asl belgilar to'plamiga aylantirish mumkin emas.

Qachon foydalanish

The Unicode Consortium suggests thinking of Muvofiqlikni tartibga solish like a ToUpperCase transform. It is something that may be useful in some circumstances, but you should not just apply it willy-nilly.

ga mos kelish uchun 9 ni qidirishni xohlaganingizdan beri mukammal foydalanish hollari qidiruvi bo'lishi mumkin.

One thing you should probably not do is display the result of applying Muvofiqlikni tartibga solish to the user.

NFKK/NFKD

Muvofiqlikni tartibga solish form comes in two forms NFKD and NFKC. They have the same relationship as between NFD and C.

NFKKdagi har qanday magistral NFC da va NFKD va NFD uchun ham xuddi shundaydir. NFKD (x) = NFD (NFKC (x)) va NFKC (x) = NFC (NFKD (x))

Xulosa

If in doubt, go with Kanonik normallashtirish. Choose NFC or NFD based on the space/speed trade-off applicable, or based on what is required by something you are inter-operating with.

165
qo'shib qo'ydi
Siz doimo NFD ga kiritilgan barcha satrlarni eng birinchi narsa deb bilasiz va NFC barcha satrlari eng oxirgi narsa sifatida chiqadi. Bu yaxshi ma'lum.
qo'shib qo'ydi muallif tchrist, manba
@Kevin: Ha, NFD va NFC tashqaridagi singletonlarni yo'q qiladi. Ishonchim komilki, kimdir bularga g'amxo'rlik qiladi, balki ehtimol.
qo'shib qo'ydi muallif tchrist, manba
Qisqartmalarning nimani anglatishini tezda eslab qoling: NF = normallashgan shakl dekompressiya = muvofiqligi ("S" olinganligi uchun) C = yozing (siqish) K .
qo'shib qo'ydi muallif Mike Spross, manba
"NFC tagidagi ikki satrni taqqoslash, ularni NFD ostida taqqoslash bilan har doim bir xil natijani beradi", lekin " normalizatsiya barqarorligi bo'limi "[...] Agar belgilanmagan belgilarga ega bo'lmagan satr Unicodening bitta versiyasi bo'yicha normallashtirilsa, Unicode ning kelajakdagi barcha versiyalarida normallashtirilishi kerak." Shunday qilib, agar Q-karon keyingi versiyada kiritilsa va siz Q + karon tarkibiy qismini Q-caron magistraliga solishtirishga harakat qilsangiz, NFC shakli ekvivalent emas, lekin NFD shakli bo'lishi kerak. Bu to'g'rimi?
qo'shib qo'ydi muallif Aurimas, manba
@tchrist: Bu, odatda, yaxshi maslahatdir, lekin noyob holatlardan tashqari, hech qanday o'zgartirishlar kiritilmasa, mahsulotning byte uchun baytga o'xshashligini xohlaysiz. NFC xotirasida yoki NFD diskida siz istagan boshqa hollar mavjud, ammo ular qoidani emas, balki exeption.
qo'shib qo'ydi muallif Kevin Cathcart, manba
Buni o'ylashingiz mumkin, ammo qo'shimcha: "Unicode stragini ma'lum bir Unicode Normalizatsiya shakliga aylantirish uchun birinchi qadam mag'lubiyatni butunlay parchalashdir". Shunday qilib, NFC bilan ishlaydigan bo'lsak, Q-Caron avval Q + Caronga aylanadi va barqarorlik qoidalari yangi kompozitsiyani xaritalashni taqiqlaydi, shuning uchun uni qayta tuza olmaydi. NFC samarali tarzda NFC (x) = Recompose (NFD (x)) sifatida aniqlanadi.
qo'shib qo'ydi muallif Kevin Cathcart, manba

Ba'zi belgilar, masalan, diqqatli harf (masalan, é ) ikki shaklda ifodalanishi mumkin - bitta kod nuqtasi U + 00E9 yoki oddiy xat aksent belgisini birlashtirgan U + 0065 U + 0301 . Oddiy me'yorlash, har doim uni ifodalash uchun ulardan birini tanlaydi (NFC uchun yagona kod nuqtasi, NFD uchun biriktiruvchi shakl).

Asosiy belgilarning bir nechta ketma-ketligi va markalarni birlashtiradigan belgilar uchun (masalan, yuqoridagi nuqta, yuqorida nuqta, yuqorida nuqta qo'yib, quyida nuqta qo'yib yoki nuqta nuqsoni bo'lgan asosiy belgi yordamida) bo'lishi mumkin bo'lgan belgilar uchun NFD shuningdek, ulardan birini tanlang (pastda, oldin sodir bo'ladi)

Muvofiqlik dekompozitsiyalari "haqiqiy emas" belgilaridan iborat bo'lgan bir qator belgilarni o'z ichiga oladi, chunki ular eski kodlashlarda ishlatilgan. Odatdagi normalizatsiya bularni birlashtirishga imkon bermaydi (yumshatilishning yaxlitligini saqlab qolish uchun - bu birlashtiruvchi shakllar uchun masala emas, chunki hech qanday eski kodlash mavjud emas [har ikkisi ham ishlatilgan bir hovuch Vyetnam kodlashidan tashqari], lekin muvofiqlik normallashuvi bo'ladi. Ba'zi Sharqiy Osiyo kodlashlarida (yoki yarmilik/katakana va alifbo) yoki "MacRoman" da "fi" ligaturasida ko'ringan "kg" kilogrammli belgini eslang.

Batafsil ma'lumot uchun http://unicode.org/reports/tr15/ .

38
qo'shib qo'ydi
Bu, albatta, to'g'ri javob. Agar siz ba'zi bir eski belgilar to'plamidan kelib chiqqan matnda faqat kanonik normallashuvdan foydalansangiz, natija ushbu belgilar majmuasiga halok bo'lmasdan aylantirilishi mumkin. Agar moslik dekompozitsiyasidan foydalansangiz, siz hech qanday muvofiqlik belgilarisiz yakunlanasiz, ammo asl belgilar to'plamiga zarar yetkazmasdan aylantirish mumkin emas.
qo'shib qo'ydi muallif Kevin Cathcart, manba

Oddiy shakllar (Unicode emas, ma'lumotlar bazalari) birinchi navbatda (faqat?) Diakritik belgilari bo'lgan belgilar bilan ishlaydi. Unicode U + 00C0, "Lotin Capital A with Grave" singari diakritik belgilar bilan "qurilgan" ba'zi belgilarni beradi. Xuddi shu belgi "Lotin Capital A" (U + 0041) dan "Combine Grave Accent" (U + 0300) bilan yaratilishi mumkin.Bu degani, ikkita ketma-ketlik bir xil natijaga ega belgi hosil qilsa ham, byte-byte taqqoslash ularni butunlay boshqacha qilib ko'rsatadi.

Normalizatsiya bu bilan shug'ullanishga urinishdir. Normallashtiruvchi barcha belgilar xuddi shu tarzda kodlanganini (yoki hech bo'lmaganda ishlaydi) - kerak bo'lganda alohida birlashtiruvchi diakritik belgini yoki hammasi bitta kod nuqtasini iloji boricha ishlatishdan iborat. Taqqoslash nuqtai nazaridan, siz tanlagan ko'plab narsa muhim emas - juda ko'p normallashtirilgan magistral boshqa normalizatsiya qilingan mag'lubiyat bilan to'g'ri taqqoslanadi.

Bunday holda, "muvofiqlik" bir kod nuqtasi bitta belgiga teng deb hisoblaydigan kod bilan muvofiqligi degan ma'noni anglatadi. Agar sizda bunday kod mavjud bo'lsa, unda siz odatdagidek oddiy shakldan foydalanishni xohlaysiz. Garchi men uni to'g'ridan-to'g'ri ko'rmagan bo'lsam-da, odatiy shakllarning nomlari Unikode konsortsiumi alohida tanqidiy belgilarni birlashtirib ishlatish afzalligini anglatadi. Buning uchun simvoldagi haqiqiy belgilarni hisoblash uchun ko'proq aql talab etiladi (shuningdek, mag'lubiyatni oqilona buzish kabi narsalar), ammo ko'p jihatdan ko'p.

Agar siz ICUdan to'liq foydalanishni istasangiz, ehtimol sizning an'anaviy an'anaviy shaklni ishlatishni xohlaysiz. O'zingizning kodingizni yozishga harakat qilsangiz, (masalan) kod nuqtasini belgilarga teng deb hisoblasangiz, ehtimol imkon qadar tezroq bajaradigan moslikning an'anaviy shaklini xohlaysiz.

13
qo'shib qo'ydi
Shuning uchun Grapheme vazifalari tarkibiga kiradigan qismdir. . Faqat ASCII-dan ko'proq belgilar emas, balki bir nechta ketma-ketlik bitta belgidan iborat bo'lishi mumkinmi? ( MB string
qo'shib qo'ydi muallif Xeoncross, manba
@ Random832 Bu to'g'ri emas. Sizning "kabaca" sizning u erda juda ko'p. Ikkala grafemani, ō va ȭ ni ko'rib chiqing. Ulardan har birini yozish uchun juda ko'p usullar mavjud, ulardan biri NFC va bitta NFD bo'lib, boshqalari ham bor. Hech qanday hodisa faqat bitta kod nuqtasi. Birinchisi uchun NFD "u \ x {332} \ x {303} \ x {304}" va NFC "\ x {22D} \ x {332}" . Ikkinchi NFD uchun "u \ x {332} \ x {304} \ x {303}" va NFC "\ x {14D} \ x {332} \ x { 303} ". Biroq, kanonik jihatdan juda ko'p imkoniyat mavjud bo'lib, bu ularga kanonik jihatdan tengdir. Normalizatsiya kanonik jihatdan o'xshash grafekalarning o'zaro taqqoslashiga imkon beradi.
qo'shib qo'ydi muallif tchrist, manba
@ Random832: Xo'p, juda to'g'ri. O'tgan ikki yil mobaynida men bilan birga ishlamaganimdan xotiradan chiqib ketishdan ko'ra bilish kerak.
qo'shib qo'ydi muallif Jerry Coffin, manba
Yo'q, "bitta kod nuqtasi bitta belgidir" taxminan NFCga to'g'ri keladi (birlashtiruvchi belgilar bilan NFD va ulardan hech biri "muvofiqlik" deb nomlanadi) - NFKC/NFKD muvofiqligi normativlari boshqa masala. eski kodlashlar uchun uyg'unlik (yoki etishmasligi); yunon mu va "mikro" uchun alohida belgilar mavjud edi (u "uyg'unlik" versiyasi Lotin 1 blokida bo'lganligi sababli u uchun qiziqarli bo'lgan)
qo'shib qo'ydi muallif Random832, manba

Ikki unikodli satr kanonik jihatdan mos keladigan bo'lsa, faqat unikodli ketma-ketlikdan foydalanib, satrlar aslida bir xil. Misol uchun, Ä yoki A belgisi yoki ◌ - kombinatsiyasini ishlatish bilan ifodalash mumkin.

Agar satrlar faqat moslik ekvivalent bo'lsa, satrlar mutlaqo bir xil bo'lmasa-da, ayrim kontekstlarda bir xil bo'lishi mumkin. Masalan, ff, ff kabi bir xil bo'lishi mumkin.

Shunday qilib, agar siz simvollarni taqqoslasangiz, sizning teng huquqlilik shartligini qo'llashingiz kerak, chunki muvofiqlik ekvivalentligi haqiqiy ekvivalent emas.

Agar siz bir qator qatorlarni saralashni istasangiz, unda moslik tengligini qo'llash mantiqiy bo'lishi mumkin, chunki deyarli bir xil.

5
qo'shib qo'ydi

Bu aslida juda oddiy. UTF-8 aslida bir xil "belgi" ning bir necha xil ko'rinishlariga ega. (Iqtibos belgilaridan foydalanaman, chunki byte-wise ular farq qiladi, lekin amalda ular bir xil). Misol bilan bog'liq hujjatda berilgan.

"Ch" belgisi 0xc387 byte qatori sifatida ifodalanishi mumkin. Lekin u C (0x43) va keyin 0x8ccca7 byte qatori bilan ifodalanishi mumkin. Demak, 0xc387 va 0x438ccca7 bir xil belgi. Ishlaydigan sabab, 0x8ccca7 birlashtiruvchi belgidir; ya'ni, undan oldingi belgini oladi (bu erda C ) va uni o'zgartiradi.

Endi, kanonik ekvivalentlik va boshqalar uyg'unligi ekvivalentligi o'rtasidagi farqga qaraganda, umumiy belgilarga qarashimiz kerak.

2 turdagi belgilar mavjud, ular qiymati orqali ma'noni yetkazadigan va boshqa belgini olgan va o'zgartiradiganlar mavjud. Shunday qilib, 9 - bu mazmunli belgi. Super skript bu ma'noni oladi va uni taqdimot bilan o'zgartiradi. Shunday qilib, ular turli xil ma'nolarga ega, ammo ular hali ham asosiy belgini anglatadi.

Shunday qilib, kanonik ekvivalentlik baytlarning ketma-ketligi xuddi shu ma'noga ega bo'lgan belgini keltirib chiqaradi. Baytning ketma-ketligi bir xil asosiy ma'noga ega bo'lgan boshqa belgilar (u o'zgarishi mumkin bo'lsa ham) moslashuvchanligi ekvivalentligi. Shunday qilib, 9 va ⁹ ikkalasi ham "9" degan ma'noni anglatadi, ammo bunga o'xshash vakolatga ega emasligi sababli, kanonik jihatdan ekvivalent emas.

Umid qilamanki ...

4
qo'shib qo'ydi
Javob: Yana javobni o'qing. Men hech qachon bir xil kod nuqtasini ifodalashning turli usullarini eslatib o'tmaganman. Men bir xil bosilgan belgini ko'rsatishning bir necha yo'llari borligini aytdim (kombinatorlar va bir nechta belgilar orqali). Qaysi UTF-8 va Unicode uchun ham amal qiladi. Demak, sizning pastga tushishingiz va sharhingiz, aytganlarimga amal qilmaydi. Aslida, asosan, bu erda eng yaxshi afishada yaratilgan (garchi u emas, balki) ...
qo'shib qo'ydi muallif ircmaxell, manba

Kanonik ekvivalentlik yoki moslik ekvivalentligi siz uchun muhimroq bo'ladimi, sizning ilovangizga bog'liq. Jadvaldagi taqqoslashlar haqidagi ASCII uslubi kabaca kanonik ekvivalentlik xaritalarini aks ettiradi, ammo Unicode ko'p tillarni ifodalaydi. Unicode barcha tillarni, xuddi G'arbiy Evropa ASCII singari, ularni davolashga imkon beradigan tarzda kodlashini tasavvur qilish xavfsiz deb o'ylamayman.

Figures 1 and 2 provide good examples of the two types of equivalence. Under compatibility equivalence, it looks like the same number in sub- and super- script form would compare equal. But I'm not sure that solve the same problem that as the cursive arabic form or the rotated characters.

Unicode matnni qayta ishlash jarayonining qattiq haqiqati, sizning ilovangizning matnni qayta ishlash talablari haqida chuqur o'ylab ko'rishingiz va keyin ularni qo'llashingiz mumkin bo'lgan vositalar bilan ham bog'lashingiz kerak. Bu sizning savolingizga to'g'ridan-to'g'ri javob bermaydi, lekin batafsil javob siz qo'llab-quvvatlaydigan har bir til uchun lisoniy mutaxassislarni talab qiladi.

4
qo'shib qo'ydi

satrlarni taqqoslash muammosi: ko'pgina ilovalarning maqsadlari uchun mos keladigan ikkita satr turli belgi ketma-ketligini o'z ichiga olishi mumkin.

See Unicode's canonical equivalence: if the comparison algorithm is simple (or must be fast), the Unicode equivalence is not performed. This problem occurs, for instance, in xml canonical comparison, see http://www.w3.org/TR/xml-c14n

Ushbu muammoni bartaraf qilish uchun ... Qaysi standart ishlatiladi? "UTF8" yoki "yilni yangi UTF8" kengaytirilganmi? "Ç" yoki "c + wūb" dan foydalaning.

W3C va boshqalar (masalan fayl nomlari ) "tasavvur qilib yaratilgan" ("eng" ixcham "qisqa simlar) ... Shunday qilib,

The standard is C! in doubt use NFC

Interoperativlik uchun va noreferrer"> "konfiguratsion konfiguratsiya" tanlovlari uchun tavsiya etilganligi uchun > NFC , tashqi satrlarni "canonize" qilish uchun. Kanonik xml saqlash uchun, masalan, uni "FORM_C" da saqlang. W3C-ning Veb ishchi guruhidagi CSV -ga ham tavsiya eting. NFC (7.2-bo'lim).

PS: "FORM_C" da kutubxonalarning aksariyatida standart shakl dir. Ex. PHP ning normalizer.isnormalized() qismida.


Ther term "compostion form" (FORM_C) is used to both, to say that "a string is in the C-canonical form" (the result of a NFC transformation) and to say that a transforming algorithm is used... See http://www.macchiato.com/unicode/nfc-faq

(...) quyidagi ketma-ketliklarning har biri (birinchi ikkita bitta belgilar ketma-ketligi) bir xil belgini aks ettiradi:

     
      
  1. U + 00C5 (A) LATIN KAPITAL MAKTUBI YUKLAB OLING
  2.   
  3. U + 212B (A) ANGSTROM SIGNI
  4.   
  5. U + 0041 (A) LATIN SAVDO MAKTUBI A + U + 030A (̊) KOMBINING RING TOMONLAR
  6.   
     

Ushbu ketma-ketliklar kanonik jihatdan ekvivalent deb ataladi. Ushbu shakllarning birinchisi "N" deb nomlanadi - C normallashtirish shaklida C, bu erda C kompostion uchun dir.   (...) S funktsiyasi S ning NFC formatiga aylantirilishi funktsiyani toNFC (S) sifatida qisqartirish mumkin, S ning NFCda ekanligini tekshiradigan kishi isNFC (S) .


Eslatma: kichik satrlarni (sof UTF-8 yoki XML-shaxslar zikrlari) me'yorini sinash uchun bu test/onlayn konvertorni normalizatsiya qilish .

1
qo'shib qo'ydi
Xristian @userfuser sizni dasturga nisbatan kerak bo'lishi mumkin: matnni yoki standartlashtirish uchun matningizmi? Mening postim faqat "standartlashtirish" ilovalari haqida. PS: butun dunyo standartni qo'llaganida, solishtirma muammo yo'qoladi.
qo'shib qo'ydi muallif Peter Krauss, manba
Men chalg'ib ketdim. Ushbu onlayn tester sahifasiga bordim va u erga kirdim: "TÖST MASh." va barcha me'yorlar 4 ni sinab ko'ring - hech kim mening matnni hech qanday tarzda o'zgartirmaydi, faqatgina u bu belgilarni taqdim etish uchun ishlatiladigan kodlarni o'zgartiradi. "Normalizatsiya" barcha diakritlarni va shunga o'xshash narsalarni olib tashlashni anglatuvchi xato deb o'ylayman va bu aslida ostidagi utf kodini o'zgartirishni anglatadimi?
qo'shib qo'ydi muallif userfuser, manba
PhP |BotsUz
PhP |BotsUz
93 ishtirokchilar

Phpni o'rganishni Hohlasangiz https://t.me/joinchat/AAAAAE-KRc5dd5tPMmGmWA A'zo bo'lin