Kif is-sorti tal-Linux issortja kordi

Introduzzjoni

Kollox beda b'kitba qasira li suppost kellha tikkombina l-informazzjoni dwar l-indirizz e-mail impjegati miksuba mil-lista tal-utenti tal-lista tal-posta, b'pożizzjonijiet tal-impjegati miksuba mid-database tad-dipartiment tal-HR. Iż-żewġ listi ġew esportati lejn fajls tat-test Unicode UTF-8 u salvati bit-truf tal-linja Unix.

Kontenut mail.txt

Иванов Андрей;[email protected]

Kontenut buhg.txt

Иванова Алла;маляр
Ёлкина Элла;крановщица
Иванов Андрей;слесарь
Абаканов Михаил;маляр

Biex jingħaqdu, il-fajls ġew magħżula mill-kmand Unix tip u sottomessi għall-input tal-programm Unix jingħaqdu, li falla b'mod mhux mistenni bi żball:

$> sort buhg.txt > buhg.srt
$> sort mail.txt > mail.srt
$> join buhg.srt mail.srt > result
join: buhg.srt:4: is not sorted: Иванов Андрей;слесарь

Meta tara r-riżultat tal-issortjar b'għajnejk uriet li, b'mod ġenerali, l-għażla hija korretta, iżda fil-każ ta' koinċidenza ta' kunjomijiet maskili u femminili, dawk femminili jiġu qabel dawk maskili:

$> sort buhg.txt
Абаканов Михаил;маляр
Ёлкина Элла;крановщица
Иванова Алла;маляр
Иванов Андрей;слесарь

Jidher qisu glitch tal-issortjar fl-Unicode jew qisu manifestazzjoni tal-feminiżmu fl-algoritmu tal-issortjar. L-ewwel huwa, ovvjament, aktar plawsibbli.

Ejja npoġġuha għalissa jingħaqdu u tiffoka fuq tip. Ejja nippruvaw insolvu l-problema billi tuża poking xjentifiku. L-ewwel, ejja nibdlu l-lokal minn en_US fuq ru_RU. Biex issolvi, ikun biżżejjed li tiġi stabbilita l-varjabbli ambjentali LC_COLLATE, imma mhux se nitilfu l-ħin fuq bagalja:

$> LANG=ru_RU.UTF-8 sort buhg.txt
Абаканов Михаил;маляр
Ёлкина Элла;крановщица
Иванова Алла;маляр
Иванов Андрей;слесарь

Xejn ma nbidel.

Ejja nippruvaw nikkodjaw mill-ġdid il-fajls f'kodifikazzjoni ta' byte wieħed:

$> iconv -f UTF-8 -t KOI8-R buhg.txt 
 | LANG=ru_RU.KOI8-R sort 
 | iconv -f KOI8-R -t UTF8

Għal darb'oħra xejn ma nbidel.

M'hemm xejn li tista 'tagħmel, inti ser ikollok tfittex soluzzjoni fuq l-Internet. M'hemm xejn direttament dwar kunjomijiet Russi, iżda hemm mistoqsijiet dwar oddities oħra ta 'għażla. Per eżempju, hawn problema: Unix sort tittratta l-karattri '-' (sing) bħala inviżibbli. Fil-qosor, il-kordi "a-b", "aa", "ac" huma magħżula bħala "aa", "a-b", "ac".

It-tweġiba hija standard kullimkien: uża l-programmer locale "C" u int tkun kuntent. Ejja nipruvaw:

$> LANG=C sort buhg.txt
Ёлкина Элла;крановщица
Абаканов Михаил;маляр
Иванов Андрей;слесарь
Иванова Алла;адвокат

Xi ħaġa nbidlet. L-Ivanovs ħejjew fl-ordni korretta, għalkemm Yolkina żelqet xi mkien. Ejja nerġgħu lura għall-problema oriġinali:

$> LANG=C sort buhg.txt > buhg.srt
$> LANG=C sort mail.txt > mail.srt
$> LANG=C join buhg.srt mail.srt > result

Ħadem mingħajr żbalji, kif wiegħed l-Internet. U dan minkejja Yolkina fl-ewwel linja.

Il-problema tidher li ġiet solvuta, iżda fil-każ, ejja nippruvaw kodifikazzjoni Russa oħra - Windows CP1251:

$> iconv -f UTF-8 -t CP1251 buhg.txt 
 | LANG=ru_RU.CP1251 sort 
 | iconv -f CP1251 -t UTF8 

Ir-riżultat tal-issortjar, b'mod stramb, se jikkoinċidi mal-lokal "C", u l-eżempju kollu, għaldaqstant, jimxi mingħajr żbalji. Xi tip ta’ mistiku.

Ma nħobbx il-mistika fl-ipprogrammar għax normalment jaħbi l-iżbalji. Ikollna nħarsu bis-serjetà kif taħdem. tip u x'jaffettwa? LC_COLLATE .

Fl-aħħar nipprova nwieġeb il-mistoqsijiet:

  • għaliex il-kunjomijiet tan-nisa ġew magħżula ħażin?
  • għaliex LANG=ru_RU.CP1251 irriżulta li kien ekwivalenti LANG=Ċ
  • għaliex tip и jingħaqdu ideat differenti dwar l-ordni tal-kordi magħżula
  • għaliex hemm żbalji fl-eżempji kollha tiegħi?
  • finalment kif issortja l-kordi kif Predisposizzjoni tiegħek

Issortjar fl-Unicode

L-ewwel waqfa tkun ir-rapport tekniku Nru 10 intitolat Algoritmu ta' kollation Unicode online unicode.org. Ir-rapport fih ħafna dettalji tekniċi, għalhekk ħalluni nagħti sommarju qasir tal-ideat ewlenin.

kollazzjoni — "tqabbil" kordi hija l-bażi ta 'kwalunkwe algoritmu ta' għażla. L-algoritmi nfushom jistgħu jvarjaw ("bużżieqa", "għaqda", "veloċi"), iżda kollha se jużaw paragun ta 'par ta' kordi biex jiddeterminaw l-ordni li fiha jidhru.

Issortjar kordi fil-lingwa naturali hija problema pjuttost kumplessa. Anke fl-aktar kodifikazzjoni ta 'byte wieħed, l-ordni ta' l-ittri fl-alfabett, anki b'xi mod differenti mill-alfabett Latin Ingliż, ma tibqax tikkoinċidi ma 'l-ordni tal-valuri numeriċi li bihom dawn l-ittri huma kodifikati. Allura fl-alfabett Ġermaniż l-ittra Ö stands bejn О и P, u fil-kodifikazzjoni CP850 hi gets bejn ÿ и Ü.

Tista 'tipprova tagħmel astratt minn kodifikazzjoni speċifika u tikkunsidra ittri "ideali" li huma rranġati f'xi ordni, kif isir fl-Unicode. Kodifikazzjonijiet UTF8, UTF16 jew byte wieħed KOI8-R (jekk ikun meħtieġ subsett limitat ta' Unicode) jagħti rappreżentazzjonijiet numeriċi differenti ta' ittri, iżda jirreferi għall-istess elementi tat-tabella bażi.

Jirriżulta li anki jekk nibnu tabella ta 'simboli mill-bidu, ma nkunux nistgħu nassenjawha ordni ta' simbolu universali. F'alfabeti nazzjonali differenti li jużaw l-istess ittri, l-ordni ta 'dawn l-ittri tista' tkun differenti. Per eżempju, bil-Franċiż Æ se titqies bħala ligatura u magħżula bħala spag AE. Fin-Norveġiż Æ se tkun ittra separata, li tinsab wara Z. Mill-mod, minbarra ligatures simili Æ Hemm ittri miktuba b'diversi simboli. Allura fl-alfabett Ċek hemm ittra Ch, li tinsab bejn H и I.

Minbarra d-differenzi fl-alfabeti, hemm tradizzjonijiet nazzjonali oħra li jinfluwenzaw l-għażla. B'mod partikolari, tqum il-mistoqsija: f'liema ordni għandhom jidhru fid-dizzjunarju kliem li jikkonsistu f'ittri kbar u żgħar? L-issortjar jista' jkun affettwat ukoll mill-użu ta' marki ta' punteġġjatura. Fl-Ispanjol, fil-bidu ta’ sentenza interrogattiva tintuża marka ta’ mistoqsija maqluba (Tħobb il-mużika?). F'dan il-każ, huwa ovvju li s-sentenzi interrogattivi m'għandhomx jinġabru fi gruppi separati barra l-alfabett, imma kif issortja linji b'marki ta 'punteġġjatura oħra?

Mhux se noqgħod fuq l-għażla ta' kordi f'lingwi differenti ħafna minn dawk Ewropej. Innota li f'lingwi b'direzzjoni tal-kitba mil-lemin għax-xellug jew minn fuq għal isfel, il-karattri fil-linji x'aktarx huma maħżuna fl-ordni tal-qari, u anke sistemi ta 'kitba mhux alfabetika għandhom il-modi tagħhom kif jordnaw il-linji karattru b'karattru. . Pereżempju, il-ġeroglifi jistgħu jiġu ordnati skont l-istil (Ċwievet tal-karattri Ċiniżi) jew bil-pronunzja. Biex inkun onest, m'għandi l-ebda idea kif għandhom jiġu rranġati l-emojis, imma tista' toħroġ b'xi ħaġa għalihom ukoll.

Ibbażat fuq il-karatteristiċi elenkati hawn fuq, ġew ifformulati r-rekwiżiti bażiċi għat-tqabbil ta' kordi bbażati fuq tabelli Unicode:

  • paragun ta 'kordi ma jiddependix fuq il-pożizzjoni tal-karattri fit-tabella tal-kodiċi;
  • sekwenzi ta' karattri li jiffurmaw karattru wieħed huma mnaqqsa għal forma kanonika (A + iċ-ċirku ta 'fuq huwa l-istess bħal Å);
  • Meta tqabbel is-sekwenza, karattru jitqies fil-kuntest tas-sekwenza u, jekk meħtieġ, ikkombinat mal-ġirien tiegħu f'unità waħda ta' tqabbil (Ch fiċ-Ċek) jew hija maqsuma f'diversi (Æ Bil-franċiż);
  • il-karatteristiċi nazzjonali kollha (alfabett, kbar/ittri żgħar, punteġġjatura, ordni tat-tipi ta' kitba) għandhom jiġu kkonfigurati sal-assenjazzjoni manwali tal-ordni (emoji);
  • it-tqabbil huwa importanti mhux biss għall-issortjar, iżda wkoll f'ħafna postijiet oħra, pereżempju biex jiġu speċifikati firxiet ta' ringieli (biex tissostitwixxi {A... z} f' bash);
  • il-paragun għandu jsir pjuttost malajr.

Barra minn hekk, l-awturi tar-rapport ifformulaw proprjetajiet ta 'tqabbil li l-iżviluppaturi tal-algoritmi m'għandhomx jiddependu fuqhom:

  • l-algoritmu ta' tqabbil m'għandux jeħtieġ sett separat ta' karattri għal kull lingwa (il-lingwi Russi u Ukrajni jaqsmu l-biċċa l-kbira tal-karattri Ċirilliċi);
  • it-tqabbil m'għandux jiddependi fuq l-ordni tal-karattri fit-tabelli Unicode;
  • piż tas-sekwenza m'għandux ikun attribut tas-sekwenza, peress li l-istess spag f'kuntesti kulturali differenti jista 'jkollu piżijiet differenti;
  • il-piżijiet tal-fillieri jistgħu jinbidlu meta jingħaqdu jew jinqasam (minn x < y ma jsegwix dan xz < yz);
  • kordi differenti li għandhom l-istess piżijiet huma kkunsidrati ugwali mil-lat tal-algoritmu tal-issortjar. L-introduzzjoni ta' ordni addizzjonali ta' kordi bħal dawn hija possibbli, iżda tista' tiddegrada l-prestazzjoni;
  • Matul issortjar ripetut, ringieli bl-istess piżijiet jistgħu jiġu skambjati. Ir-robustezza hija proprjetà ta' algoritmu ta' għażla speċifiku, u mhux proprjetà ta' algoritmu ta' tqabbil ta' string (ara l-paragrafu preċedenti);
  • Ir-regoli tal-għażla jistgħu jinbidlu maż-żmien hekk kif it-tradizzjonijiet kulturali jirfinaw/jinbidlu.

Huwa stipulat ukoll li l-algoritmu ta 'tqabbil ma jaf xejn dwar is-semantika tal-kordi li qed jiġu pproċessati. Għalhekk, kordi li jikkonsistu biss f'ċifri m'għandhomx jitqabblu bħala numri, u f'listi ta' ismijiet bl-Ingliż l-artiklu (Beatles, The).

Sabiex jiġu ssodisfati r-rekwiżiti speċifikati kollha, huwa propost algoritmu ta' għażla ta' tabella b'ħafna livelli (fil-fatt f'erba' livelli).

Preċedentement, il-karattri fis-sekwenza huma mnaqqsa għal forma kanonika u miġbura f'unitajiet ta 'paragun. Kull unità ta' tqabbil hija assenjata diversi piżijiet li jikkorrispondu għal diversi livelli ta' tqabbil. Il-piżijiet ta 'unitajiet ta' tqabbil huma elementi ta 'settijiet ordnati (f'dan il-każ, numri interi) li jistgħu jitqabblu għal aktar jew inqas. Tifsira speċjali INJORATA (0x0) tfisser li fil-livell ta' tqabbil korrispondenti din l-unità mhix involuta fit-tqabbil. Il-paragun tal-kordi jista 'jiġi ripetut diversi drabi, bl-użu tal-piżijiet tal-livelli korrispondenti. F'kull livell, il-piżijiet tal-unitajiet ta 'tqabbil ta' żewġ ringieli jitqabblu b'mod sekwenzjali ma 'xulxin.

F'implimentazzjonijiet differenti tal-algoritmu għal tradizzjonijiet nazzjonali differenti, il-valuri tal-koeffiċjenti jistgħu jvarjaw, iżda l-istandard Unicode jinkludi tabella bażika tal-piżijiet - "Tabella ta' Elementi ta' Kollazzjoni Unicode default" (DUCET). Nixtieq ninnota li l-issettjar tal-varjabbli LC_COLLATE hija fil-fatt indikazzjoni tal-għażla tat-tabella tal-piż fil-funzjoni ta 'tqabbil ta' string.

Koeffiċjenti tal-piż DUCET irranġat kif ġej:

  • fl-ewwel livell, l-ittri kollha jitnaqqsu għall-istess każ, id-dijakritiċi jintremew, il-marki tal-punteġġjatura (mhux kollha) jiġu injorati;
  • fit-tieni livell, jitqiesu biss id-dijakritiċi;
  • fit-tielet livell, il-każ biss jitqies;
  • fir-raba' livell, il-marki tal-punteġġjatura biss jitqiesu.

It-tqabbil iseħħ f'diversi passes: l-ewwel, jitqabblu l-koeffiċjenti tal-ewwel livell; jekk il-piżijiet jikkoinċidu, imbagħad jitwettaq paragun ripetut mal-piżijiet tat-tieni livell; imbagħad forsi t-tielet u r-raba’.

Il-paragun jintemm meta r-ringieli jkun fihom unitajiet ta' tqabbil li jaqblu ma' piżijiet differenti. Ringieli li għandhom piżijiet ugwali fl-erba 'livelli kollha huma kkunsidrati ugwali għal xulxin.

Dan l-algoritmu (b'mazz ta 'dettalji tekniċi addizzjonali) ta l-isem li jirrapporta Nru 10 - "Algoritmu ta' Kollazzjoni Unicode" (ACU).

Dan huwa fejn l-imġieba tal-issortjar mill-eżempju tagħna ssir ftit aktar ċara. Ikun sabiħ li titqabbel mal-istandard Unicode.

Biex tittestja l-implimentazzjonijiet ACU hemm speċjali test, bl-użu fajl tal-piżijiet, implimentazzjoni DUCET. Tista 'ssib kull xorta ta' affarijiet umoristiċi fil-fajl tal-iskali. Pereżempju, hemm l-ordni tal-mahjong u d-dominoes Ewropej, kif ukoll l-ordni tal-ilbiesi f’gverta ta’ karti (simbolu 1F000 u aktar). L-ilbiesi tal-karti jitqiegħdu skont ir-regoli tal-pont - PCBT, u l-karti fil-libsa huma fis-sekwenza T, 2,3, XNUMX... K.

Iċċekkja manwalment li r-ringieli huma magħżula b'mod korrett skond DUCET ikun pjuttost tedjanti, iżda, fortunatament għalina, hemm implimentazzjoni eżemplari tal-librerija biex taħdem ma 'Unicode - "Komponenti Internazzjonali għal Unicode"(ICU).

Fuq il-websajt ta’ din il-librerija, żviluppat fi IBM, hemm paġni demo, inklużi paġna tal-algoritmu tal-paragun tal-istring. Aħna nidħlu fil-linji tat-test tagħna b'settings default u, ara u ara, niksbu għażla perfetta Russa.

Абаканов Михаил;маляр
Ёлкина Элла;крановщица
Иванов Андрей;слесарь
Иванова Алла;адвокат

Mill-mod, il-websajt ICU Tista' ssib kjarifika tal-algoritmu ta' tqabbil meta tipproċessa l-marki tal-punteġġjatura. Fl-eżempji Kollazzjoni FAQ appostrofu u sing huma injorati.

Unicode għenuna, imma nfittxu raġunijiet għal imġieba stramba tip в Linux se jkollu jmur x'imkien ieħor.

Issortjar fil-glibc

Ħarsa ta 'malajr tal-kodiċijiet tas-sors tal-utilità tip ta ' GNU Core Utils wera li fl-utilità nnifisha, il-lokalizzazzjoni jaqa 'għall-istampar tal-valur kurrenti tal-varjabbli LC_COLLATE meta taħdem fil-modalità debug:

$ sort --debug buhg.txt > buhg.srt
sort: using ‘en_US.UTF8’ sorting rules

Il-paraguni tal-istring jitwettqu bl-użu tal-funzjoni standard strcoll, li jfisser li kollox interessanti jinsab fil-librerija glibc.

Fuq wiki il-proġett glibc iddedikat għat-tqabbil tal-kordi paragrafu wieħed. Minn dan il-paragrafu jista’ jinftiehem li fil glibc issortjar huwa bbażat fuq algoritmu diġà magħruf lilna ACU (L-algoritmu ta' kollation Unicode) u/jew fi standard qrib tiegħu ISO 14651 (Kord internazzjonali u paragun). Rigward l-aħħar standard, għandu jiġi nnutat li fuq is-sit standards.iso.org ISO 14651 uffiċjalment iddikjarat disponibbli pubblikament, iżda l-link korrispondenti twassal għal paġna ineżistenti. Google jirritorna diversi paġni b’links għal siti uffiċjali li joffru li jixtru kopja elettronika tal-istandard għal mitt ewro, iżda fit-tielet jew ir-raba’ paġna tar-riżultati tat-tfittxija hemm ukoll links diretti għal PDF. B'mod ġenerali, l-istandard prattikament mhuwiex differenti minn ACU, iżda huwa aktar boring biex jinqara minħabba li ma fihx eżempji ċari ta 'karatteristiċi nazzjonali ta' għażla ta 'korda.

L-aktar informazzjoni interessanti fuq wiki kien hemm link għal bug tracker b'diskussjoni dwar l-implimentazzjoni ta 'paragun ta' string in glibc. Mid-diskussjoni jista’ jitgħallem li glibc użati biex iqabblu kordi ISOmejda personali It-Tabella tal-Mudelli Komuni (CTT), li l-indirizz tiegħu jinsab fl-applikazzjoni A standard ISO 14651. Bejn l-2000 u l-2015 din it-tabella fi glibc ma kellux manutenzjoni u kien pjuttost differenti (għall-inqas esternament) mill-verżjoni attwali tal-istandard. Mill-2015 sal-2018, sar adattament għall-verżjoni l-ġdida tat-tabella, u issa għandek iċ-ċans li tiltaqa 'fil-ħajja reali verżjoni ġdida tat-tabella (CentOS 8), u qodma (CentOS 7).

Issa li għandna l-informazzjoni kollha dwar l-algoritmu u t-tabelli awżiljarji, nistgħu nerġgħu lura għall-problema oriġinali u nifhmu kif issolvi b'mod korrett kordi fil-lokal Russu.

ISO 14651 / 14652

Kodiċi tas-sors tat-tabella li aħna interessati fiha CTT fuq il-biċċa l-kbira tad-distribuzzjonijiet Linux jinsab fil-katalgu /usr/share/i18n/locales/. It-tabella nnifisha tinsab fil-fajl iso14651_t1_common. Imbagħad din hija d-direttiva tal-fajl kopja iso14651_t1_common inkluż fil-fajl iso14651_t1, li, min-naħa tagħha, hija inkluża fil-fajls nazzjonali, inklużi en_US и ru_RU. Fuq il-biċċa l-kbira tad-distribuzzjonijiet Linux il-fajls tas-sors kollha huma inklużi fl-installazzjoni bażika, imma jekk ma jkunux preżenti, ikollok tinstalla pakkett addizzjonali mid-distribuzzjoni.

Struttura tal-fajl iso14651_t1 jista 'jidher terriblement verbose, b'regoli mhux ovvji għall-kostruzzjoni ta' ismijiet, imma jekk tħares lejha, ​​kollox huwa pjuttost sempliċi. L-istruttura hija deskritta fl-istandard ISO 14652, li kopja tagħha tista' titniżżel mill-websajt open-std.org. Deskrizzjoni oħra tal-format tal-fajl tista 'tinqara fi speċifikazzjonijiet POSIX minn OpenGroup. Bħala alternattiva għall-qari tal-istandard, tista 'tistudja l-kodiċi tas-sors tal-funzjoni kollate_read в glibc/locale/programs/ld-collate.c.

L-istruttura tal-fajl tidher bħal din:

B'mod awtomatiku, il-karattru jintuża bħala karattru escape, u t-tmiem tal-linja wara l-karattru # huwa kumment. Iż-żewġ simboli jistgħu jiġu definiti mill-ġdid, li huwa dak li jsir fil-verżjoni l-ġdida tat-tabella:

escape_char /
comment_char %

Il-fajl se jkun fih tokens fil-format jew (Fejn x - ċifra eżadeċimali). Din hija r-rappreżentazzjoni eżadeċimali tal-punti tal-kodiċi Unicode fil-kodifikazzjoni UCS-4 (UTF-32). L-elementi l-oħra kollha fil-parentesi angolari (inkluż , <2> u affarijiet simili) huma kkunsidrati kostanti ta' string sempliċi li ftit għandhom tifsira barra mill-kuntest.

Linja LC_COLLATE jgħidilna li jmiss jibda d-data li tiddeskrivi l-paragun ta 'kordi.

L-ewwel, l-ismijiet huma speċifikati għall-piżijiet fit-tabella tat-tqabbil u l-ismijiet għall-kombinazzjonijiet tas-simboli. B'mod ġenerali, iż-żewġ tipi ta 'ismijiet jappartjenu għal żewġ entitajiet differenti, iżda fil-fajl attwali huma mħallta. L-ismijiet tal-piżijiet huma speċifikati mill-kelma prinċipali tiġbor-simbolu (karattru ta' tqabbil) għaliex meta jitqabblu, karattri Unicode li għandhom l-istess piżijiet se jitqiesu bħala karattri ekwivalenti.

It-tul totali tas-sezzjoni fir-reviżjoni tal-fajl attwali huwa madwar 900 linja. Ġibt eżempji minn diversi postijiet biex nuri l-arbitrjetà tal-ismijiet u diversi tipi ta’ sintassi.

LC_COLLATE

collating-symbol <RES-1>
collating-symbol <BLK>
collating-symbol <MIN>
collating-symbol <WIDE>
...
collating-symbol <ARABIC>
collating-symbol <ETHPC>
collating-symbol <OSMANYA>
...
collating-symbol <S1D000>..<S1D35F>
collating-symbol <SFFFF> % Guaranteed largest symbol value. Keep at end of this list
...
collating-element <U0413_0301> from "<U0413><U0301>"
collating-element <U0413_0341> from "<U0413><U0341>"

  • kollating-simbolu zkuk string OSMANJA fit-tabella tal-ismijiet tal-iskali
  • kollating-simbolu .. jirreġistra sekwenza ta' ismijiet li jikkonsistu fi prefiss S u suffiss numeriku eżadeċimali minn 1D000 li 1D35F.
  • FFFF в simbolu tal-ġbir jidher qisu numru sħiħ mhux iffirmat kbir f'ħeksadeċimali, iżda huwa biss isem li jista 'jidher qisu
  • isem tfisser il-punt tal-kodiċi fil-kodifikazzjoni UCS-4
  • element ta' ġbir minn "" jirreġistra isem ġdid għal par tikek Unicode.

Ladarba l-ismijiet tal-piżijiet huma definiti, il-piżijiet attwali huma speċifikati. Peress li huma biss relazzjonijiet akbar minn inqas importanti meta mqabbla, il-piżijiet huma determinati minn sekwenza sempliċi ta 'ismijiet ta' lista. Il-piżijiet "eħfef" huma elenkati l-ewwel, imbagħad dawk "itqal". Ħa nfakkarkom li kull karattru Unicode huwa assenjat erba' piżijiet differenti. Hawnhekk huma magħquda f'sekwenza ordnata waħda. Fit-teorija, kwalunkwe isem simboliku jista 'jintuża fi kwalunkwe mill-erba' livelli, iżda l-kummenti jindikaw li l-iżviluppaturi mentalment separati l-ismijiet f'livelli.

% Symbolic weight assignments

% Third-level weight assignments
<RES-1>
<BLK>
<MIN>
<WIDE>
...
% Second-level weight assignments
<BASE>
<LOWLINE> % COMBINING LOW LINE
<PSILI> % COMBINING COMMA ABOVE
<DASIA> % COMBINING REVERSED COMMA ABOVE
...
% First-level weight assignments
<S0009> % HORIZONTAL TABULATION 
<S000A> % LINE FEED
<S000B> % VERTICAL TABULATION
...
<S0434> % CYRILLIC SMALL LETTER DE
<S0501> % CYRILLIC SMALL LETTER KOMI DE
<S0452> % CYRILLIC SMALL LETTER DJE
<S0503> % CYRILLIC SMALL LETTER KOMI DJE
<S0453> % CYRILLIC SMALL LETTER GJE
<S0499> % CYRILLIC SMALL LETTER ZE WITH DESCENDER
<S0435> % CYRILLIC SMALL LETTER IE
<S04D7> % CYRILLIC SMALL LETTER IE WITH BREVE
<S0454> % CYRILLIC SMALL LETTER UKRAINIAN IE
<S0436> % CYRILLIC SMALL LETTER ZHE

Fl-aħħarnett, it-tabella tal-piżijiet attwali.

It-taqsima tal-piżijiet hija magħluqa f'linji tal-kliem kjavi order_start и order_end. Għażliet żejda order_start tiddetermina f'liema direzzjoni r-ringieli jiġu skennjati f'kull livell ta' paragun. L-issettjar default huwa quddiem. Il-korp tas-sezzjoni jikkonsisti f'linji li fihom il-kodiċi tas-simbolu u l-erba' piżijiet tiegħu. Il-kodiċi tal-karattru jista 'jiġi rappreżentat mill-karattru innifsu, punt ta' kodiċi, jew isem simboliku definit qabel. Il-piżijiet jistgħu wkoll jingħataw lil ismijiet simboliċi, punti ta 'kodiċi, jew is-simboli nfushom. Jekk jintużaw punti jew karattri tal-kodiċi, il-piż tagħhom huwa l-istess bħall-valur numeriku tal-punt tal-kodiċi (pożizzjoni fit-tabella Unicode). Karattri mhux speċifikati b'mod espliċitu (kif nifhem jien) huma kkunsidrati assenjati għat-tabella b'piż primarju li jaqbel mal-pożizzjoni fit-tabella Unicode. Valur tal-piż speċjali INJORA ifisser li s-simbolu jiġi injorat fil-livell xieraq ta’ tqabbil.

Biex nuri l-istruttura tal-iskali, għażilt tliet frammenti pjuttost ovvji:

  • karattri li huma kompletament injorati
  • simboli ekwivalenti għan-numru tlieta fl-ewwel żewġ livelli
  • il-bidu tal-alfabett Ċirilliku, li ma fihx dijakritiċi, u għalhekk huwa magħżul prinċipalment mill-ewwel u t-tielet livelli.

order_start forward;forward;forward;forward,position
<U0000> IGNORE;IGNORE;IGNORE;IGNORE % NULL (in 6429)
<U0001> IGNORE;IGNORE;IGNORE;IGNORE % START OF HEADING (in 6429)
<U0002> IGNORE;IGNORE;IGNORE;IGNORE % START OF TEXT (in 6429)
...
<U0033> <S0033>;<BASE>;<MIN>;<U0033> % DIGIT THREE
<UFF13> <S0033>;<BASE>;<WIDE>;<UFF13> % FULLWIDTH DIGIT THREE
<U2476> <S0033>;<BASE>;<COMPAT>;<U2476> % PARENTHESIZED DIGIT THREE
<U248A> <S0033>;<BASE>;<COMPAT>;<U248A> % DIGIT THREE FULL STOP
<U1D7D1> <S0033>;<BASE>;<FONT>;<U1D7D1> % MATHEMATICAL BOLD DIGIT THREE
...
<U0430> <S0430>;<BASE>;<MIN>;<U0430> % CYRILLIC SMALL LETTER A
<U0410> <S0430>;<BASE>;<CAP>;<U0410> % CYRILLIC CAPITAL LETTER A
<U04D1> <S04D1>;<BASE>;<MIN>;<U04D1> % CYRILLIC SMALL LETTER A WITH BREVE
<U0430_0306> <S04D1>;<BASE>;<MIN>;<U04D1> % CYRILLIC SMALL LETTER A WITH BREVE
...
<U0431> <S0431>;<BASE>;<MIN>;<U0431> % CYRILLIC SMALL LETTER BE
<U0411> <S0431>;<BASE>;<CAP>;<U0411> % CYRILLIC CAPITAL LETTER BE
<U0432> <S0432>;<BASE>;<MIN>;<U0432> % CYRILLIC SMALL LETTER VE
<U0412> <S0432>;<BASE>;<CAP>;<U0412> % CYRILLIC CAPITAL LETTER VE
...
order_end

Issa tista 'terġa' lura għall-issortjar tal-eżempji mill-bidu tal-artiklu. L-imbuska tinsab f'din il-parti tat-tabella tal-piżijiet:

<U0020> IGNORE;IGNORE;IGNORE;<U0020> % SPACE
<U0021> IGNORE;IGNORE;IGNORE;<U0021> % EXCLAMATION MARK
<U0022> IGNORE;IGNORE;IGNORE;<U0022> % QUOTATION MARK
...

Wieħed jista’ jara li f’din it-tabella l-marki tal-punteġġjatura mit-tabella ASCII (inkluż l-ispazju) huwa kważi dejjem injorat meta jitqabblu kordi. L-uniċi eċċezzjonijiet huma linji li jaqblu f'kollox ħlief marki ta' punteġġjatura misjuba f'pożizzjonijiet li jaqblu. Il-linji mill-eżempju tiegħi (wara l-għażla) għall-algoritmu ta 'tqabbil jidhru bħal dan:

АбакановМихаилмаляр
ЁлкинаЭллакрановщица
ИвановаАлламаляр
ИвановАндрейслесарь

Meta wieħed iqis li fit-tabella tal-iskali, ittri kapitali bir-Russu jiġu wara ittri żgħar (fit-tielet livell itqal minn ), l-issortjar jidher assolutament korrett.

Meta tissettja varjabbli LC_COLLATE=C titgħabba tabella speċjali li tispeċifika paragun byte b'byte

static const uint32_t collseqwc[] =
{
  8, 1, 8, 0x0, 0xff,
  /* 1st-level table */
  6 * sizeof (uint32_t),
  /* 2nd-level table */
  7 * sizeof (uint32_t),
  /* 3rd-level table */
  L'x00', L'x01', L'x02', L'x03', L'x04', L'x05', L'x06', L'x07',
  L'x08', L'x09', L'x0a', L'x0b', L'x0c', L'x0d', L'x0e', L'x0f',

...
  L'xf8', L'xf9', L'xfa', L'xfb', L'xfc', L'xfd', L'xfe', L'xff'
};

Peress li fl-Unicode il-punt tal-kodiċi Ё jiġi qabel A, is-sekwijiet huma magħżula kif xieraq.

Test u tabelli binarji

Ovvjament, il-paragun tal-istring huwa operazzjoni estremament komuni, u parsing tat-tabella CTT proċedura pjuttost għalja. Biex jiġi ottimizzat l-aċċess għat-tabella, hija miġbura f'forma binarja bil-kmand localdef.

Team localdef jaċċetta bħala parametri fajl b'tabella ta' karatteristiċi nazzjonali (għażla -i), li fiha l-karattri kollha huma rappreżentati minn tikek Unicode, u fajl ta’ korrispondenza bejn tikek Unicode u karattri ta’ kodifikazzjoni speċifika (għażla -f). Bħala riżultat tax-xogħol, jinħolqu fajls binarji għal-lokal bl-isem speċifikat fl-aħħar parametru.

glibc jappoġġja żewġ formati ta 'fajls binarji: "tradizzjonali" u "modern".

Il-format tradizzjonali jfisser li l-isem tal-lokal huwa l-isem tas-subdirettorju fi /usr/lib/locale/. Dan is-subdirettorju jaħżen fajls binarji LC_COLLATE, LC_CTYPE, LC_TIME u l-bqija. Fajl LC_IDENTIFIKAZZJONI fih l-isem formali tal-lokal (li jista' jkun differenti mill-isem tad-direttorju) u kummenti.

Il-format modern jinvolvi l-ħażna tal-lokalijiet kollha f'arkivju wieħed /usr/lib/locale/locale-archive, li hija mmappjata mal-memorja virtwali tal-proċessi kollha li jużaw glibc. L-isem tal-lokal fil-format modern huwa soġġett għal xi kanonizzazzjoni - numri u ittri mnaqqsa biss f'ittri żgħar jibqgħu fl-ismijiet tal-kodifikazzjoni. Allura ru_RU.KOI8-R, se jiġu ffrankati bħala ru_RU.koi8r.

Fajls tal-input huma mfittxija fid-direttorju attwali, kif ukoll fid-direttorji /usr/share/i18n/locales/ и /usr/share/i18n/charmaps/ għall-fajls CTT u fajls ta' kodifikazzjoni, rispettivament.

Per eżempju, il-kmand

localedef -i ru_RU -f MAC-CYRILLIC ru_RU.MAC-CYRILLIC

se jikkompila l-fajl /usr/share/i18n/locales/ru_RU bl-użu tal-fajl tal-kodifikazzjoni /usr/share/i18n/charmaps/MAC-CYRILLIC.gz u ssalva r-riżultat fi /usr/lib/locale/locale-archive taħt l-isem ru_RU.maccyrillic

Jekk issettja l-varjabbli LANG = en_US.UTF-8 li glibc se tfittex binarji lokali fis-sekwenza ta 'fajls u direttorji li ġejjin:

/usr/lib/locale/locale-archive
/usr/lib/locale/en_US.UTF-8/
/usr/lib/locale/en_US/
/usr/lib/locale/enUTF-8/
/usr/lib/locale/en/

Jekk lokalità sseħħ kemm fil-format tradizzjonali kif ukoll f'format modern, allura tingħata prijorità lil dak modern.

Tista' tara l-lista ta' lokalitajiet miġbura bil-kmand locale -a.

Tħejjija t-tabella tat-tqabbil tiegħek

Issa, armat bl-għarfien, tista 'toħloq it-tabella ta' tqabbil ideali tiegħek stess. Din it-tabella għandha tqabbel b'mod korrett ittri Russi, inkluża l-ittra Ё, u fl-istess ħin tqis il-marki tal-punteġġjatura skont it-tabella ASCII.

Il-proċess tal-preparazzjoni tat-tabella tal-issortjar tiegħek jikkonsisti f'żewġ stadji: l-editjar tat-tabella tal-piżijiet u l-kumpilazzjoni tagħha f'forma binarja bil-kmand localdef.

Sabiex it-tabella ta 'tqabbil tiġi aġġustata bi spejjeż minimi ta' editjar, fil-format ISO 14652 Sezzjonijiet għall-aġġustament tal-piżijiet ta 'tabella eżistenti huma pprovduti. It-taqsima tibda b'kelma prinċipali ordni mill-ġdid wara u tindika l-pożizzjoni li warajha titwettaq is-sostituzzjoni. Is-sezzjoni tispiċċa bil-linja ordni mill-ġdid-tmiem. Jekk ikun meħtieġ li jiġu kkoreġuti diversi sezzjonijiet tat-tabella, allura tinħoloq sezzjoni għal kull sezzjoni bħal din.

I kkupjati verżjonijiet ġodda tal-fajls iso14651_t1_common и ru_RU mir-repożitorju glibc fid-direttorju tad-dar tiegħi ~/.local/share/i18n/locales/ u editjat kemmxejn is-sezzjoni LC_COLLATE в ru_RU. Verżjonijiet ġodda tal-fajls huma kompletament kompatibbli mal-verżjoni tiegħi glibc. Jekk trid tuża verżjonijiet eqdem tal-fajls, ikollok tibdel l-ismijiet simboliċi u l-post fejn jibda s-sostituzzjoni fit-tabella.

LC_COLLATE
% Copy the template from ISO/IEC 14651
copy "iso14651_t1"
reorder-after <U000D>
<U0020> <S0020>;<BASE>;<MIN>;<U0020> % SPACE
<U0021> <S0021>;<BASE>;<MIN>;<U0021> % EXCLAMATION MARK
<U0022> <S0022>;<BASE>;<MIN>;<U0022> % QUOTATION MARK
...
<U007D> <S007D>;<BASE>;<MIN>;<U007D> % RIGHT CURLY BRACKET
<U007E> <S007E>;<BASE>;<MIN>;<U007E> % TILDE
reorder-end
END LC_COLLATE

Fil-fatt, ikun meħtieġ li jinbidlu l-oqsma fil LC_IDENTIFIKAZZJONI sabiex jippuntaw lejn il-lokal ru_MY, iżda fl-eżempju tiegħi dan ma kienx meħtieġ, peress li esklujt l-arkivju mit-tfittxija għal lokalitajiet lokali-arkivju.

Li localdef ħadem ma 'fajls fil-folder tiegħi permezz ta' varjabbli I18NPATH Tista 'żżid direttorju addizzjonali biex tfittex fajls ta' input, u d-direttorju biex jiġu salvati fajls binarji jista 'jiġi speċifikat bħala mogħdija bi slashes:

$> I18NPATH=~/.local/share/i18n localedef -i ru_RU -f UTF-8 ~/.local/lib/locale/ru_MY.UTF-8

POSIX jissuġġerixxi li fi BISS tista 'tikteb mogħdijiet assoluti għal direttorji b'fajls lokali, li jibdew bi mmejla 'l quddiem, iżda glibc в Linux il-mogħdijiet kollha jingħaddu mid-direttorju bażi, li jista 'jiġi sostitwit permezz ta' varjabbli LOCPATH. Wara l-installazzjoni LOCPATH=~/.local/lib/locale/ il-fajls kollha relatati mal-lokalizzazzjoni se jiġu mfittxija biss fil-folder tiegħi. Arkivju ta' lokalitajiet bis-sett varjabbli LOCPATH injorat.

Hawn hu t-test deċiżiv:

$> LANG=ru_MY.UTF-8 LOCPATH=~/.local/lib/locale/ sort buhg.txt
Абаканов Михаил;маляр
Ёлкина Элла;крановщица
Иванов Андрей;слесарь
Иванова Алла;адвокат

Ħura! Għamilna!

Xi żbalji

Diġà wieġeb il-mistoqsijiet dwar l-issortjar tal-istring li saru fil-bidu, iżda għad hemm ftit mistoqsijiet dwar żbalji - viżibbli u inviżibbli.

Ejja nerġgħu lura għall-problema oriġinali.

U l-programm tip u l-programm jingħaqdu uża l-istess funzjonijiet ta 'tqabbil ta' string minn glibc. Kif ġara hekk jingħaqdu ta żball fl-issortjar fuq ringieli magħżula mill-kmand tip fil-lokal en_US.UTF-8? It-tweġiba hija sempliċi: tip tqabbel is-sekwenza kollha, u jingħaqdu tqabbel biss iċ-ċavetta, li awtomatikament hija l-bidu tas-sekwenza sal-ewwel karattru ta' spazju abjad. Fl-eżempju tiegħi, dan irriżulta f'messaġġ ta 'żball minħabba li l-għażla tal-ewwel kliem fil-linji ma kinitx taqbel mal-għażla tal-linji kompluti.

Lokali "C" jiggarantixxi li fi strings magħżula s-substrings inizjali sal-ewwel spazju se jiġu magħżula wkoll, iżda dan jaħbi biss l-iżball. Huwa possibbli li tagħżel data (nies bl-istess kunjomijiet, iżda kunjomijiet differenti) li, mingħajr il-messaġġ ta 'żball, tagħti riżultat ta' amalgamazzjoni ta 'fajls mhux korrett. Jekk irridu jingħaqdu linji tal-fajl magħquda bl-isem sħiħ, allura l-mod korrett ikun li tispeċifika espliċitament is-separatur tal-qasam u ssortja mill-qasam ewlieni, u mhux bil-linja kollha. F'dan il-każ, l-amalgamazzjoni tipproċedi b'mod korrett u ma jkun hemm l-ebda żball fl-ebda lokalità:

$> sort -t ; -k 1 buhg.txt > buhg.srt
$> sort -t ; -k 1 mail.txt > mail.srt
$> join -t ; buhg.srt mail.srt > result

Eżempju esegwit b'suċċess fil-kodifikazzjoni CP1251 fih żball ieħor. Il-fatt hu li fid-distribuzzjonijiet kollha magħrufa lili Linux pakketti huma neqsin locale kkumpilat ru_RU.CP1251. Jekk il-lokal miġbur ma jinstabx, allura tip skiet juża paragun byte b'byte, li huwa dak li osservajna.

Mill-mod, hemm glitch żgħir ieħor relatat ma 'l-inaċċessibbiltà ta' lokalitajiet ikkumpilati. Tim LOCPATH=/tmp locale -a se tagħti lista tal-lokalijiet kollha fi lokali-arkivju, iżda bis-sett varjabbli LOCPATH għall-programmi kollha (inkluż l-aktar locale) dawn il-lokal mhux se jkunu disponibbli.

$> LOCPATH=/tmp locale -a | grep en_US
locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_MESSAGES to default locale: No such file or directory
locale: Cannot set LC_COLLATE to default locale: No such file or directory
en_US
en_US.iso88591
en_US.iso885915
en_US.utf8

$> LC_COLLATE=en_US.UTF-8 sort --debug
sort: using ‘en_US.UTF-8’ sorting rules

$> LOCPATH=/tmp LC_COLLATE=en_US.UTF-8 sort --debug
sort: using simple byte comparison

Konklużjoni

Jekk inti programmatur li huwa mdorri biex taħseb li l-kordi huma sett ta 'bytes, allura l-għażla tiegħek LC_COLLATE=C.

Jekk inti lingwista jew kompilatur tad-dizzjunarju, allura aħjar tikkompila fil-lokal tiegħek.

Jekk inti utent sempliċi, allura għandek bżonn biss li jidraw il-fatt li l-kmand ls -a joħroġ fajls li jibdew b'tikka mħallta ma' fajls li jibdew b'ittra, u Kmandant ta ’Nofsillejl, li juża l-funzjonijiet interni tiegħu stess biex issolvi l-ismijiet, ipoġġi fajls li jibdew b'tikka fil-bidu tal-lista.

referenzi

Rapport Nru 10 algoritmu ta' kollazzjoni Unicode

Piżijiet tal-karattri fuq unicode.org

ICU — implimentazzjoni ta' librerija biex taħdem ma' Unicode minn IBM.

Issortjar test bl-użu ICU

Il-piżijiet tal-karattri fi ISO 14651

Deskrizzjoni tal-format tal-fajl bi skali ISO 14652

Diskussjoni tal-paragun tal-istring in glibc

Sors: www.habr.com

Żid kumment