Giunsa paghan-ay sa Linux ang mga string

Pasiuna

Nagsugod ang tanan sa usa ka mubo nga script nga kinahanglan nga maghiusa sa kasayuran sa address sa e-mail mga empleyado nga nakuha gikan sa lista sa mga tiggamit sa mailing list, nga adunay mga posisyon sa empleyado nga nakuha gikan sa database sa departamento sa HR. Ang duha ka listahan gi-eksport sa Unicode text files UTF-8 ug gitipigan gamit ang Unix line endings.

Kontento mail.txt

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

Kontento buhg.txt

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

Aron mahiusa, ang mga file gisunod sa Unix command matang ug gisumite sa input sa programa sa Unix apil, nga wala damha napakyas sa usa ka sayup:

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

Ang pagtan-aw sa resulta sa paghan-ay sa imong mga mata nagpakita nga, sa kinatibuk-an, ang paghan-ay husto, apan sa kaso sa mga sulagma sa lalaki ug babaye nga mga apelyido, ang mga babaye nag-una sa mga lalaki:

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

Morag usa ka glitch sa paghan-ay sa Unicode o sama sa pagpakita sa pagkababaye sa algorithm sa paghan-ay. Ang una, siyempre, mas katuohan.

Ato kining ihunong sa pagkakaron apil ug focus sa matang. Atong sulayan nga sulbaron ang problema gamit ang scientific poking. Una, usbon nato ang lokal nga gikan sa en_US sa ru_RU. Aron maihap, igo na nga itakda ang variable sa palibot LC_COLLATE, apan dili kami mag-usik ug panahon sa mga butang nga walay hinungdan:

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

Walay nausab.

Atong sulayan pag-recode ang mga file ngadto sa usa ka byte nga encoding:

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

Usa pa walay nausab.

Wala ka'y ​​mahimo, kinahanglan nimo pangitaon ang solusyon sa Internet. Wala’y direkta nga bahin sa mga apelyido sa Russia, apan adunay mga pangutana bahin sa uban pang mga lahi nga lahi. Pananglitan, aniay problema: Ang unix sort nagtratar sa '-' (dash) nga mga karakter nga dili makita. Sa laktod nga pagkasulti, ang mga kuwerdas nga "ab", "aa", "ac" gihan-ay nga "aa", "ab", "ac".

Ang tubag mao ang sukaranan bisan diin: gamita ang lokal nga programmer "C" ug magmalipayon ka. Atong sulayan:

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

Adunay nausab. Ang mga Ivanov naglinya sa husto nga han-ay, bisan kung si Yolkina nahulog sa usa ka dapit. Balikan nato ang orihinal nga problema:

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

Nagtrabaho kini nga wala’y mga sayup, ingon sa gisaad sa Internet. Ug kini bisan pa sa Yolkina sa unang linya.

Morag nasulbad na ang problema, pero in case lang, sulayan nato ang laing Russian encoding - Windows CP1251:

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

Ang resulta sa paghan-ay, sa katingad-an, motakdo sa lokal "C", ug ang tibuok nga pananglitan, sumala niana, midagan nga walay mga sayop. Usa ka matang sa mistisismo.

Dili ko ganahan sa mistisismo sa pagprograma tungod kay kasagaran kini nagtago sa mga sayup. Kinahanglan natong seryosohon nga tan-awon kung giunsa kini paglihok. matang ug unsay epekto niini? LC_COLLATE .

Sa katapusan ako mosulay sa pagtubag sa mga pangutana:

  • nganong sayop ang pagkahan-ay sa mga apelyido sa babaye?
  • ngano LANG=ru_RU.CP1251 nahimo nga katumbas LANG=C
  • nganong buhaton matang и apil lain-laing mga ideya mahitungod sa han-ay sa mga han-ay sa mga kuwerdas
  • nganong naay mga sayop sa tanan nakong mga ehemplo?
  • sa katapusan kung unsaon paghan-ay ang mga kuwerdas sa imong gusto

Pag-sort sa Unicode

Ang unang hunonganan mao ang technical report No. 10 nga nag-ulohan Algoritmo sa pagkolekta sa Unicode Online unicode.org. Ang taho adunay daghang teknikal nga detalye, busa tugoti ako nga maghatag usa ka mubo nga katingbanan sa mga nag-unang ideya.

maampingong pagsusi — Ang "pagtandi" sa mga kuwerdas mao ang sukaranan sa bisan unsang algorithm sa paghan-ay. Ang mga algorithm mismo mahimong magkalainlain ("bubble", "merge", "fast"), apan silang tanan mogamit usa ka pagtandi sa usa ka parisan sa mga kuldas aron mahibal-an ang pagkasunud kung diin kini makita.

Ang paghan-ay sa mga string sa natural nga pinulongan usa ka medyo komplikado nga problema. Bisan sa pinakasimple nga single-byte nga pag-encode, ang han-ay sa mga letra sa alpabeto, bisan sa usa ka paagi nga lahi sa English Latin nga alpabeto, dili na motakdo sa han-ay sa mga numeric values ​​diin kini nga mga letra gi-encode. Busa sa German nga alpabeto ang letra Ö nagbarog taliwala О и P, ug sa pag-encode CP850 siya makakuha sa taliwala ÿ и Ü.

Mahimo nimong sulayan ang pag-abstract gikan sa usa ka piho nga pag-encode ug ikonsiderar ang "ideal" nga mga letra nga gihan-ay sa pila ka han-ay, sama sa gibuhat sa Unicode. Mga pag-encode UTF8, UTF16 o usa ka byte KOI8-R (kung gikinahanglan ang limitado nga subset sa Unicode) maghatag ug lain-laing numeric nga representasyon sa mga letra, apan maghisgot sa samang elemento sa base table.

Kini nahimo nga bisan kung magtukod kami usa ka lamesa sa simbolo gikan sa wala, dili kami makahimo sa pag-assign sa usa ka unibersal nga han-ay sa simbolo niini. Sa lain-laing nasodnong alpabeto nga naggamit ug samang mga letra, ang han-ay niini nga mga letra mahimong magkalahi. Pananglitan, sa Pranses Æ pagaisipon nga usa ka litid ug ihan-ay ingon usa ka hilo AE. Sa Norwegian Æ mahimong usa ka bulag nga sulat, nga nahimutang pagkahuman Z. Pinaagi sa dalan, dugang pa sa mga ligature sama Æ Adunay mga letra nga gisulat nga adunay daghang mga simbolo. Busa sa Czech alpabeto adunay usa ka letra Ch, nga nagbarog taliwala H и I.

Dugang pa sa mga kalainan sa mga alpabeto, adunay uban nga mga nasudnong tradisyon nga nag-impluwensya sa paghan-ay. Sa partikular, ang pangutana mitungha: sa unsa nga han-ay ang mga pulong nga naglangkob sa dagko ug gagmay nga mga letra makita sa diksyonaryo? Ang paghan-ay mahimo usab nga maapektuhan sa paggamit sa mga punctuation mark. Sa Kinatsila, ang usa ka balit-ad nga marka sa pangutana gigamit sa sinugdanan sa usa ka interrogative sentence (Ganahan ka ba sa musika?). Sa kini nga kaso, dayag nga ang mga interogatibo nga mga tudling-pulong kinahanglan dili igrupo sa usa ka bulag nga kumpol sa gawas sa alpabeto, apan kung giunsa ang paghan-ay sa mga linya sa ubang mga marka sa punctuation?

Dili ako maghisgot sa paghan-ay sa mga kuwerdas sa mga pinulongan nga lahi kaayo sa mga European. Timan-i nga sa mga pinulongan nga adunay right-to-left o top-to-bottom nga direksyon sa pagsulat, ang mga karakter sa mga linya lagmit nga gitipigan sa pagkahan-ay sa pagbasa, ug bisan ang dili alpabetikong mga sistema sa pagsulat adunay ilang kaugalingong mga paagi sa pag-order sa mga linya sa karakter sa karakter. . Pananglitan, ang mga hieroglyph mahimong orderon pinaagi sa estilo (Mga yawe sa mga karakter sa Intsik) o pinaagi sa paglitok. Sa tinuud, wala ako nahibal-an kung giunsa ang paghan-ay sa mga emojis, apan mahimo ka usab maghimo usa ka butang alang kanila.

Pinasukad sa mga bahin nga gilista sa ibabaw, ang sukaranan nga mga kinahanglanon alang sa pagtandi sa mga kuwerdas base sa mga lamesa sa Unicode giporma:

  • Ang pagtandi sa mga kuwerdas wala magdepende sa posisyon sa mga karakter sa lamesa sa code;
  • Ang mga han-ay sa mga karakter nga nagporma sa usa ka karakter gikunhoran ngadto sa kanonikal nga porma (A + ang ibabaw nga lingin parehas sa Å);
  • Kung itandi ang mga kuwerdas, ang usa ka karakter gikonsiderar sa konteksto sa hilo ug, kung kinahanglan, gihiusa sa mga silingan niini sa usa ka yunit sa pagtandi (Ch sa Czech) o gibahin ngadto sa pipila (Æ sa Pranses);
  • tanang nasyonal nga bahin (alpabeto, dako/gamay, punctuation, han-ay sa mga tipo sa pagsulat) kinahanglang i-configure hangtod sa manwal nga assignment sa order (emoji);
  • Ang pagtandi importante dili lamang sa paghan-ay, kondili sa daghang uban pang mga dapit, pananglitan sa pagtino sa mga han-ay sa laray (pag-ilis sa {A... z} sa bash);
  • ang pagtandi kinahanglan nga buhaton dayon.

Dugang pa, ang mga tagsulat sa taho nagporma sa mga kabtangan sa pagtandi nga dili kinahanglan nga saligan sa mga developer sa algorithm:

  • ang algorithm sa pagtandi kinahanglan dili magkinahanglan usa ka lahi nga hugpong sa mga karakter alang sa matag sinultian (Russian ug Ukrainian nga mga pinulongan nag-ambit sa kadaghanan nga mga karakter sa Cyrillic);
  • ang pagtandi kinahanglan dili magsalig sa han-ay sa mga karakter sa mga lamesa sa Unicode;
  • Ang gibug-aton sa hilo kinahanglan dili usa ka kinaiya sa hilo, tungod kay ang parehas nga hilo sa lainlaing konteksto sa kultura mahimong adunay lainlaing mga gibug-aton;
  • Ang mga gibug-aton sa linya mahimong mausab kung maghiusa o magbulag (gikan sa x < y wala kini nagsunod niana xz < yz);
  • Ang lainlaing mga kuwerdas nga adunay parehas nga gibug-aton giisip nga managsama gikan sa punto sa pagtan-aw sa algorithm sa pagsunud. Ang pagpaila sa dugang nga pag-order sa ingon nga mga kuwerdas posible, apan mahimo’g kini makadaot sa pasundayag;
  • Atol sa balik-balik nga paghan-ay, ang mga laray nga adunay parehas nga gibug-aton mahimong ibaylo. Ang kalig-on usa ka kabtangan sa usa ka piho nga algorithm sa paghan-ay, ug dili usa ka kabtangan sa usa ka algorithm sa pagtandi sa string (tan-awa ang miaging parapo);
  • Ang paghan-ay sa mga lagda mahimong mausab sa paglabay sa panahon samtang ang mga tradisyon sa kultura nagdalisay/nagbag-o.

Gitakda usab nga ang algorithm sa pagtandi wala’y nahibal-an bahin sa mga semantiko sa mga string nga giproseso. Busa, ang mga kuwerdas nga gilangkoban lamang sa mga digit dili angayng itandi ingong mga numero, ug sa mga lista sa Ingles nga mga ngalan ang artikulo (Beatles, Ang).

Aron matagbaw ang tanan nga gipiho nga mga kinahanglanon, usa ka multi-level (sa tinuud upat ka lebel) nga algorithm sa paghan-ay sa lamesa ang gisugyot.

Kaniadto, ang mga karakter sa hilo gipamub-an sa kanonikal nga porma ug gigrupo sa mga yunit sa pagtandi. Ang matag yunit sa pagtandi gihatagan ug daghang gibug-aton nga katumbas sa daghang lebel sa pagtandi. Ang mga gibug-aton sa mga yunit sa pagtandi mao ang mga elemento sa gimando nga mga set (sa kini nga kaso, mga integer) nga mahimong itandi sa mas daghan o dili kaayo. Espesyal nga kahulogan GAWASAY (0x0) nagpasabot nga sa katugbang nga lebel sa pagtandi kini nga yunit wala maapil sa pagtandi. Ang pagtandi sa mga kuwerdas mahimong balik-balikon sa makadaghang higayon, gamit ang mga gibug-aton sa katugbang nga lebel. Sa matag lebel, ang mga gibug-aton sa mga yunit sa pagtandi sa duha ka laray sunodsunod nga gitandi sa usag usa.

Sa lainlaing mga pagpatuman sa algorithm alang sa lainlaing nasyonal nga tradisyon, ang mga kantidad sa mga coefficient mahimong magkalainlain, apan ang sumbanan sa Unicode naglakip sa usa ka sukaranan nga lamesa sa mga gibug-aton - "Default nga Unicode Collation Element Table" (DUCET). Gusto nakong timan-an nga ang pag-set sa variable LC_COLLATE sa tinuud usa ka timailhan sa pagpili sa lamesa sa gibug-aton sa function sa pagtandi sa hilo.

Mga coefficient sa pagtimbang DUCET gihan-ay ingon sa mosunod:

  • sa una nga lebel, ang tanan nga mga letra gipamubu sa parehas nga kaso, ang mga diakritiko gisalikway, ang mga marka sa punctuation (dili tanan) wala gibalewala;
  • sa ikaduhang ang-ang, ang mga diakritiko lamang ang gikonsiderar;
  • sa ikatulo nga lebel, kaso ra ang gikonsiderar;
  • sa ikaupat nga ang-ang, mga punctuation mark lang ang gikonsiderar.

Ang pagtandi mahitabo sa daghang mga pass: una, ang mga coefficient sa unang lebel gitandi; kung ang mga gibug-aton magkatakdo, nan ang usa ka balik-balik nga pagtandi sa ikaduhang lebel nga mga gibug-aton gihimo; unya tingali ikatulo ug ikaupat.

Ang pagtandi matapos kung ang mga laray adunay managsama nga mga yunit sa pagtandi sa lainlaing mga gibug-aton. Ang mga laray nga adunay managsama nga gibug-aton sa tanan nga upat nga lebel giisip nga managsama sa usag usa.

Kini nga algorithm (nga adunay usa ka hugpong sa dugang nga teknikal nga mga detalye) naghatag sa ngalan sa pagreport sa No. 10 - "Unicode Collation Algorithm" (ACU).

Dinhi ang pagsunud sa pamatasan gikan sa among panig-ingnan nahimong mas klaro. Nindot nga itandi kini sa sumbanan sa Unicode.

Sa pagsulay sa mga pagpatuman ACU naay espesyal ang pagsulay, gamit ang timbang nga file, pagpatuman DUCET. Makita nimo ang tanang matang sa kataw-anan nga mga butang sa timbangan nga file. Pananglitan, adunay han-ay sa mahjong ug European domino, ingon man ang han-ay sa mga suit sa usa ka deck sa mga kard (simbolo 1F000 ug dugang pa). Ang mga card suit gibutang sumala sa mga lagda sa tulay - PCBT, ug ang mga kard sa suit naa sa han-ay T, 2,3, XNUMX... K.

Manwal nga pagsusi nga ang mga laray gihan-ay sa husto sumala sa DUCET makakapoy kaayo, apan, maayo na lang alang kanamo, adunay usa ka sulundon nga pagpatuman sa librarya alang sa pagtrabaho kauban ang Unicode - "Internasyonal nga mga sangkap alang sa Unicode"(ICU).

Sa website niini nga librarya, naugmad sa IBM, adunay mga panid sa demo, lakip ang panid sa algorithm sa pagtandi sa string. Gisulod namon ang among mga linya sa pagsulay nga adunay mga default nga setting ug, tan-awa, nakuha namon ang hingpit nga paghan-ay sa Ruso.

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

Pinaagi sa dalan, ang website ICU Makita nimo ang pagpatin-aw sa algorithm sa pagtandi kung giproseso ang mga marka sa punctuation. Sa mga pananglitan Koleksyon FAQ apostrophe ug hyphen gibalewala.

Gitabangan kami sa Unicode, apan pangitaa ang mga hinungdan sa katingad-an nga pamatasan matang в Linux kinahanglan nga moadto sa laing dapit.

Pagsunud sa glibc

Dali nga pagtan-aw sa mga utility source code matang gikan sa GNU Core nga mga Util nagpakita nga sa utility mismo, ang localization moabut sa pag-imprinta sa kasamtangan nga bili sa variable LC_COLLATE kung nagdagan sa debug mode:

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

Ang mga pagtandi sa string gihimo gamit ang standard function strcoll, nga nagpasabut nga ang tanan nga makapaikag naa sa librarya glibc.

sa wiki proyekto glibc gipahinungod sa pagtandi sa string usa ka paragraph. Gikan niini nga parapo masabtan nga sa glibc Ang paghan-ay gibase sa usa ka algorithm nga nahibal-an na namo ACU (Ang algorithm sa pagkolekta sa Unicode) ug/o sa usa ka sumbanan nga duol niini ISO 14651 (Pag-order ug pagtandi sa internasyonal nga string). Mahitungod sa pinakabag-o nga sumbanan, kinahanglan nga matikdan nga sa site standards.iso.org ISO 14651 opisyal nga gideklarar nga magamit sa publiko, apan ang katugbang nga link nagpadulong sa usa ka wala nga panid. Gibalik sa Google ang daghang mga panid nga adunay mga link sa opisyal nga mga site nga nagtanyag pagpalit usa ka elektronik nga kopya sa sumbanan sa usa ka gatos nga euro, apan sa ikatulo o ikaupat nga panid sa mga resulta sa pagpangita adunay direkta usab nga mga link sa PDF. Sa kinatibuk-an, ang sumbanan halos walay kalainan sa ACU, pero mas makalaay basahon tungod kay wala kiniy klarong mga pananglitan sa nasudnong mga bahin sa paghan-ay sa hilo.

Ang labing makapaikag nga impormasyon sa wiki naay link sa bug tracker uban sa usa ka diskusyon sa pagpatuman sa string nga pagtandi sa glibc. Gikan sa diskusyon mahibal-an kana glibc gigamit sa pagtandi sa mga kuwerdas ISOpersonal nga lamesa Ang Common Template Table (CTT), ang adres niini makita sa aplikasyon A sumbanan ISO 14651. Tali sa 2000 ug 2015 kini nga lamesa sa glibc walay maintainer ug lahi kaayo (labing menos sa gawas) gikan sa kasamtangan nga bersyon sa standard. Gikan sa 2015 hangtod 2018, ang pagpahiangay sa bag-ong bersyon sa lamesa nahitabo, ug karon adunay ka higayon nga makit-an sa tinuud nga kinabuhi ang usa ka bag-ong bersyon sa lamesa (CentOS 8), ug tigulang (CentOS 7).

Karon nga naa na namo ang tanang impormasyon bahin sa algorithm ug auxiliary nga mga lamesa, makabalik na kami sa orihinal nga problema ug masabtan kon unsaon paghan-ay ang mga string sa lokal nga Russian.

ISO 14651 / 14652

Source code sa lamesa nga among interesado CTT sa kadaghanan sa mga distribusyon Linux naa sa katalogo /usr/share/i18n/locales/. Ang lamesa mismo naa sa file iso14651_t1_common. Unya kini ang direktiba sa file kopyaha ang iso14651_t1_common gilakip sa file iso14651_t1, nga, sa baylo, gilakip sa nasyonal nga mga file, lakip ang en_US и ru_RU. Sa kadaghanan sa mga distribusyon Linux Ang tanan nga gigikanan nga mga file gilakip sa sukaranan nga pag-install, apan kung wala sila, kinahanglan nimo nga i-install ang usa ka dugang nga pakete gikan sa pag-apod-apod.

Istruktura sa file iso14651_t1 morag hilabihan ka verbose, nga adunay dili klaro nga mga lagda alang sa pagtukod og mga ngalan, apan kung imong tan-awon kini, ang tanan yano ra. Ang istruktura gihulagway sa sumbanan ISO 14652, usa ka kopya niini mahimong ma-download gikan sa website open-std.org. Ang laing paghulagway sa format sa file mabasa sa mga detalye POSIX gikan sa OpenGroup. Isip alternatibo sa pagbasa sa sumbanan, mahimo nimong tun-an ang source code sa function collate_read в glibc/locale/programs/ld-collate.c.

Ang istruktura sa file ingon niini:

Sa kasagaran, ang karakter gigamit isip usa ka karakter sa pag-ikyas, ug ang katapusan sa linya pagkahuman sa # karakter usa ka komento. Ang duha ka mga simbolo mahimong mabag-o, nga mao ang gibuhat sa bag-ong bersyon sa lamesa:

escape_char /
comment_char %

Ang file adunay mga token sa format o (Asa x - hexadecimal digit). Kini ang hexadecimal nga representasyon sa Unicode code points sa encoding UCS-4 (UTF-32). Ang tanan nga uban nga mga elemento sa anggulo bracket (lakip ang , <2> ug ang susama) gikonsiderar nga yano nga string constants nga adunay gamay nga kahulogan gawas sa konteksto.

Linya LC_COLLATE nagsulti kanato nga sunod magsugod ang datos nga naghulagway sa pagtandi sa mga kuwerdas.

Una, ang mga ngalan gipiho alang sa mga gibug-aton sa lamesa sa pagtandi ug mga ngalan alang sa mga kombinasyon sa simbolo. Sa kinatibuk-an, ang duha ka matang sa mga ngalan iya sa duha ka lain-laing mga entidad, apan sa aktuwal nga file sila gisagol. Ang mga ngalan sa mga gibug-aton gipiho sa keyword collating-simbolo (comparison character) tungod kay kung itandi, ang Unicode nga mga karakter nga adunay parehas nga gibug-aton isipon nga katumbas nga mga karakter.

Ang kinatibuk-ang gitas-on sa seksyon sa kasamtangan nga rebisyon sa file mga 900 ka linya. Gikuha nako ang mga pananglitan gikan sa daghang mga lugar aron ipakita ang pagkaarbitraryo sa mga ngalan ug daghang mga lahi sa syntax.

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>"

  • collating-simbolo nag-log usa ka pisi OSMANYA sa talad sa mga ngalan sa timbangan
  • collating-simbolo .. nagrehistro sa usa ka han-ay sa mga ngalan nga naglangkob sa usa ka prefix S ug hexadecimal numeric suffix gikan sa 1D000 sa 1D35F.
  • FFFF в collating-simbolo murag dako nga unsigned integer sa hexadecimal, pero kini usa lamang ka ngalan nga tingali ingon
  • имя nagpasabot sa code point sa encoding UCS-4
  • pagkolekta-elemento gikan sa" " nagparehistro og bag-ong ngalan alang sa usa ka parisan sa Unicode tuldok.

Sa diha nga ang mga ngalan sa mga gibug-aton gihubit, ang aktuwal nga mga gibug-aton gipiho. Tungod kay ang mas dako pa kay sa dili kaayo nga mga relasyon ang importante kon itandi, ang mga gibug-aton gitino pinaagi sa usa ka yano nga han-ay sa listahan sa mga ngalan. Ang "mas gaan" nga mga gibug-aton gilista una, dayon ang "mas bug-at". Pahinumdumi ko nimo nga ang matag karakter sa Unicode gihatagan ug upat ka lainlaing gibug-aton. Dinhi sila gihiusa ngadto sa usa ka ordered sequence. Sa teoriya, ang bisan unsang simbolo nga ngalan mahimong gamiton sa bisan asa sa upat ka lebel, apan ang mga komento nagpakita nga ang mga developers sa hunahuna nagbulag sa mga ngalan ngadto sa lebel.

% 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

Sa katapusan, ang aktuwal nga gibug-aton nga lamesa.

Ang seksyon sa gibug-aton gilakip sa mga linya sa keyword order_sugod и order_end. Dugang nga mga kapilian order_sugod Tinoa kung asa nga direksyon ang mga linya gi-scan sa matag lebel sa pagtandi. Ang default setting mao ang sa unahan. Ang lawas sa seksyon naglangkob sa mga linya nga adunay simbolo nga code ug ang upat nga gibug-aton niini. Ang code sa karakter mahimong irepresentar sa karakter mismo, usa ka code point, o usa ka simbolo nga ngalan nga gihubit kaniadto. Ang mga gibug-aton mahimo usab nga ihatag sa simbolikong mga ngalan, code point, o sa mga simbolo mismo. Kung gigamit ang mga punto sa kodigo o mga karakter, ang gibug-aton niini parehas sa kantidad sa numero sa punto sa code (posisyon sa lamesa sa Unicode). Ang mga karakter nga dili klaro nga espesipiko (sama sa akong nasabtan) giisip nga gi-assign sa lamesa nga adunay panguna nga gibug-aton nga mohaum sa posisyon sa lamesa sa Unicode. Espesyal nga bili sa timbang WALA NAY KAHIBALO nagpasabot nga ang simbolo wala tagda sa tukma nga lebel sa pagtandi.

Aron ipakita ang istruktura sa mga timbangan, gipili nako ang tulo nga klaro nga mga tipik:

  • mga karakter nga hingpit nga gibalewala
  • mga simbolo nga katumbas sa numero nga tulo sa unang duha ka lebel
  • ang sinugdanan sa Cyrillic nga alpabeto, nga wala maglangkob sa mga diacritics, ug busa gihan-ay sa panguna sa una ug ikatulo nga lebel.

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

Karon makabalik ka sa paghan-ay sa mga pananglitan gikan sa sinugdanan sa artikulo. Ang pagbanhig nahimutang niining bahina sa lamesa sa timbang:

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

Makita nga sa kini nga lamesa ang mga punctuation mark gikan sa lamesa ASCII (lakip ang espasyo) halos kanunay nga gibalewala kung itandi ang mga kuwerdas. Ang bugtong eksepsiyon mao ang mga linya nga motakdo sa tanan gawas sa mga punctuation mark nga makita sa magkaparehas nga posisyon. Ang mga linya gikan sa akong panig-ingnan (pagkahuman sa paghan-ay) alang sa pagtandi nga algorithm ingon niini:

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

Sa pagkonsiderar nga sa lamesa sa mga timbangan, ang dagkong mga letra sa Ruso nagsunod sa gagmay nga mga letra (sa ikatulo nga lebel mas bug-at kay sa ), ang paghan-ay tan-awon nga husto kaayo.

Kung nagbutang usa ka variable LC_COLLATE=C usa ka espesyal nga lamesa ang gikarga nga nagtino sa usa ka byte-by-byte nga pagtandi

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'
};

Tungod kay sa Unicode ang code point Ё nag-una sa A, ang mga kuwerdas gihan-ay sumala niana.

Teksto ug binary nga mga lamesa

Dayag nga, ang pagtandi sa hilo usa ka kasagaran nga operasyon, ug pag-parse sa lamesa CTT medyo mahal nga pamaagi. Aron ma-optimize ang pag-access sa lamesa, gihugpong kini sa binary nga porma nga adunay mando localdef.

team localdef nagdawat ingon nga mga parameter sa usa ka file nga adunay usa ka lamesa sa nasudnon nga mga kinaiya (opsyon -i), diin ang tanan nga mga karakter girepresentahan sa Unicode tuldok, ug usa ka file sa mga sulat tali sa Unicode tuldok ug mga karakter sa usa ka piho nga encoding (opsyon -f). Ingon usa ka sangputanan sa trabaho, ang binary nga mga file gihimo alang sa lokal nga adunay ngalan nga gitakda sa katapusan nga parameter.

glibc nagsuporta sa duha ka binary file format: "tradisyonal" ug "moderno".

Ang tradisyonal nga format nagpasabot nga ang ngalan sa lokal mao ang ngalan sa subdirectory sa /usr/lib/locale/. Kini nga subdirektoryo nagtipig binary files LC_COLLATE, LC_CTYPE, LC_TIME ug uban pa. file LC_IDENTIFICATION naglangkob sa pormal nga ngalan sa lokal (nga mahimong lahi sa ngalan sa direktoryo) ug mga komento.

Ang modernong format naglakip sa pagtipig sa tanang mga lokal sa usa ka archive /usr/lib/locale/locale-archive, nga gimapa sa virtual nga panumduman sa tanan nga mga proseso nga gigamit glibc. Ang lokal nga ngalan sa moderno nga pormat gipailalom sa pipila ka canonization - ang mga numero ug letra lang nga gipamubu sa gamay nga letra ang nagpabilin sa mga ngalan sa pag-encode. Busa ru_RU.KOI8-R, maluwas isip ru_RU.koi8r.

Ang mga input file gipangita sa kasamtangan nga direktoryo, ingon man sa mga direktoryo /usr/share/i18n/locales/ и /usr/share/i18n/charmaps/ alang sa mga file CTT ug pag-encode sa mga file, matag usa.

Pananglitan, ang sugo

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

mag-compile sa file /usr/share/i18n/locales/ru_RU gamit ang encoding file /usr/share/i18n/charmaps/MAC-CYRILLIC.gz ug i-save ang resulta sa /usr/lib/locale/locale-archive sa ilalum sa ngalan ru_RU.maccyrillic

Kung imong gibutang ang variable LANG = en_US.UTF-8 unya glibc mangita alang sa lokal nga binary sa mosunod nga han-ay sa mga file ug mga direktoryo:

/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/

Kung ang usa ka lokal mahitabo sa tradisyonal ug moderno nga mga pormat, nan ang prayoridad gihatag sa moderno.

Mahimo nimong tan-awon ang lista sa mga natipon nga lokal nga adunay mando locale -a.

Pag-andam sa imong lamesa sa pagtandi

Karon, armado sa kahibalo, makahimo ka sa paghimo sa imong kaugalingon nga sulundon nga lamesa sa pagtandi sa kuwerdas. Kini nga lamesa kinahanglan nga husto nga itandi ang mga letra nga Ruso, lakip ang letra Ё, ug sa samang higayon tagdon ang mga marka sa punctuation uyon sa lamesa ASCII.

Ang proseso sa pag-andam sa imong kaugalingon nga paghan-ay nga lamesa naglangkob sa duha ka yugto: pag-edit sa lamesa sa gibug-aton ug pag-compile niini sa binary nga porma gamit ang mando localdef.

Aron ma-adjust ang lamesa sa pagtandi nga adunay gamay nga gasto sa pag-edit, sa format ISO 14652 Ang mga seksyon alang sa pag-adjust sa gibug-aton sa usa ka kasamtangan nga lamesa gihatag. Ang seksyon nagsugod sa usa ka keyword reorder-human ug nagpaila sa posisyon nga pagkahuman gihimo ang pagpuli. Ang seksyon natapos sa linya pag-order-pagtapos. Kung gikinahanglan ang pagtul-id sa daghang mga seksyon sa lamesa, nan usa ka seksyon ang gihimo alang sa matag ingon nga seksyon.

Gikopya nako ang bag-ong mga bersyon sa mga file iso14651_t1_common и ru_RU gikan sa repository glibc sa akong home directory ~/.local/share/i18n/locales/ ug gamay nga gi-edit ang seksyon LC_COLLATE в ru_RU. Ang mga bag-ong bersyon sa mga file hingpit nga nahiuyon sa akong bersyon glibc. Kung gusto nimo gamiton ang mga daan nga bersyon sa mga file, kinahanglan nimo nga usbon ang mga simbolo nga ngalan ug ang lugar diin nagsugod ang pagpuli sa lamesa.

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

Sa tinuud, kinahanglan nga usbon ang mga natad sa LC_IDENTIFICATION aron ilang itudlo ang lokal ru_MY, apan sa akong pananglitan wala kini gikinahanglan, tungod kay wala nako iapil ang archive gikan sa pagpangita sa mga lokal lokal nga-archive.

nga localdef nagtrabaho uban sa mga file sa akong folder pinaagi sa usa ka variable I18NPATH Mahimo nimong idugang ang usa ka dugang nga direktoryo aron pangitaon ang mga file sa input, ug ang direktoryo aron matipig ang mga binary nga file mahimong ipiho ingon usa ka agianan nga adunay mga slashes:

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

POSIX nagtuo nga sa LANGUAGE mahimo nimong isulat ang hingpit nga mga agianan sa mga direktoryo nga adunay mga file sa lokal, sugod sa usa ka forward slash, apan glibc в Linux ang tanan nga mga agianan giihap gikan sa base nga direktoryo, nga mahimong ma-override pinaagi sa usa ka variable LOCPATH. Human sa pag-instalar LOCPATH=~/.local/lib/locale/ ang tanan nga mga file nga may kalabutan sa lokalisasyon pangitaon ra sa akong folder. Archive sa mga lokal nga adunay variable set LOCPATH gibalewala.

Ania ang mahukmanon nga pagsulay:

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

Hooray! Among gibuhat!

Pagtrabaho sa bug

Gitubag na nako ang mga pangutana bahin sa paghan-ay sa mga string nga gipresentar sa sinugdanan, apan adunay usa ka pares nga mga pangutana bahin sa mga sayup - makita ug dili makita.

Balik ta sa orihinal nga problema.

Ug ang programa matang ug programa apil gamita ang parehas nga mga function sa pagtandi sa string gikan sa glibc. Giunsa kini nahitabo apil naghatag usa ka sayup sa paghan-ay sa mga linya nga gisunud sa mando matang sa lokal en_US.UTF-8? Simple ra ang tubag: matang nagtandi sa tibuok hilo, ug apil nagtandi lamang sa yawe, nga sa kasagaran mao ang sinugdanan sa hilo hangtod sa unang whitespace nga karakter. Sa akong pananglitan, miresulta kini sa usa ka mensahe sa sayop tungod kay ang paghan-ay sa unang mga pulong sa mga linya dili motakdo sa paghan-ay sa kompletong linya.

Lokal "C" gigarantiyahan nga sa gihan-ay nga mga kuwerdas ang mga inisyal nga mga substring hangtod sa una nga wanang mahan-ay usab, apan kini nagtago lamang sa sayup. Posible ang pagpili sa datos (mga tawo nga parehas ang apelyido, apan lahi ang una nga ngalan) nga, kung wala ang mensahe sa sayup, maghatag usa ka dili husto nga resulta sa paghiusa sa file. Kung gusto nato apil gihiusa ang mga linya sa file pinaagi sa tibuok nga ngalan, nan ang husto nga paagi mao ang dayag nga pagpiho sa field separator ug paghan-ay sa key field, ug dili sa tibuok linya. Sa kini nga kaso, ang paghiusa magpadayon sa husto ug wala’y mga sayup sa bisan unsang lokal:

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

Malampuson nga gipatuman nga pananglitan sa pag-encode CP1251 adunay laing sayop. Ang kamatuoran mao nga sa tanan nga mga pag-apod-apod nga nahibal-an nako Linux Ang mga pakete nawala nga gihugpong nga lokal ru_RU.CP1251. Kung dili makit-an ang gihugpong nga lokal, nan matang hilom nga naggamit sa usa ka byte-by-byte nga pagtandi, nga mao ang among naobserbahan.

Pinaagi sa dalan, adunay lain nga gamay nga glitch nga may kalabutan sa pagkadili maabut sa mga natipon nga lokal. Team LOCPATH=/tmp locale -a maghatag ug lista sa tanang lokal nga lugar sa lokal nga-archive, apan uban sa variable set LOCPATH alang sa tanan nga mga programa (lakip ang kadaghanan lokal nga) kini nga mga lokal dili magamit.

$> 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

konklusyon

Kung ikaw usa ka programmer nga naanad sa paghunahuna nga ang mga kuwerdas usa ka hugpong sa mga byte, nan ang imong gipili LC_COLLATE=C.

Kung ikaw usa ka lingguwista o tigkompiler sa diksyonaryo, nan mas maayo nga mag-compile ka sa imong lokal.

Kung ikaw usa ka yano nga tiggamit, nan kinahanglan nimo nga maanad sa kamatuoran nga ang mando ls -a nagpagawas sa mga file nga nagsugod sa usa ka tulbok nga gisagol sa mga file nga nagsugod sa usa ka letra, ug Ang komandante sa tungang gabii, nga naggamit sa iyang internal nga mga gimbuhaton sa paghan-ay sa mga ngalan, nagbutang sa mga file nga nagsugod sa usa ka tulbok sa sinugdanan sa listahan.

mga pakisayran

Report No. 10 Unicode collation algorithm

Mga gibug-aton sa karakter sa unicode.org

ICU — pagpatuman sa usa ka librarya alang sa pagtrabaho uban sa Unicode gikan sa IBM.

Pagsunud sa pagsulay gamit ICU

Mga gibug-aton sa karakter sa ISO 14651

Deskripsyon sa format sa file nga adunay mga timbangan ISO 14652

Paghisgot sa pagtandi sa hilo sa glibc

Source: www.habr.com

Idugang sa usa ka comment