Mar a bhios Linux a’ seòrsachadh sreangan

Ro-ràdh

Thòisich e uile le sgriobt ghoirid a bha còir fiosrachadh seòlaidh a chur còmhla post-d luchd-obrach air fhaighinn bhon liosta de luchd-cleachdaidh liosta puist, le dreuchdan luchd-obrach air am faighinn bho stòr-dàta roinn HR. Chaidh an dà liosta às-mhalairt gu faidhlichean teacsa Unicode UTF-8 agus air a shàbhaladh le crìochnachaidhean loidhne Unix.

Susbaint post.txt

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

Susbaint buhg.txt

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

Gus aonachadh, chaidh na faidhlichean a rèiteachadh leis an àithne Unix Deasaich agus air a chuir a-steach gu cuir a-steach prògram Unix còmhla, a dh’fhàillig leis nach robh dùil le mearachd:

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

Le bhith a’ coimhead air toradh an seòrsachaidh le do shùilean sheall e gu bheil, san fharsaingeachd, an seòrsachadh ceart, ach a thaobh co-thuiteamas de shloinnidhean fireannaich is boireann, thig an fheadhainn bhoireann air beulaibh an fheadhainn fhireann:

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

A’ coimhead coltach ri glitch sorting ann an Unicode no mar fhoillseachadh air boireannachd san algairim sheòrsachaidh. Tha a 'chiad fhear, gu dearbh, nas so-chreidsinneach.

Leig leinn a chuir dheth airson a-nis còmhla agus cuir fòcas air Deasaich. Feuchaidh sinn ris an duilgheadas fhuasgladh le bhith a’ cleachdadh poking saidheansail. An toiseach, atharraichidh sinn an locale bho en_US air ru_RU. Airson a sheòrsachadh, bhiodh e gu leòr caochladair na h-àrainneachd a shuidheachadh LC_COLLATE, ach cha bhith sinn a’ caitheamh ùine air trifles:

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

Chan eil dad air atharrachadh.

Feuchaidh sinn ris na faidhlichean ath-chòdachadh ann an còdachadh aon-byte:

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

A-rithist chan eil dad air atharrachadh.

Chan eil dad as urrainn dhut a dhèanamh, feumaidh tu coimhead airson fuasgladh air an eadar-lìn. Chan eil dad gu dìreach mu dheidhinn sloinnidhean Ruiseanach, ach tha ceistean ann mu rudan eile a thaobh seòrsachadh neònach. Mar eisimpleir, seo duilgheadas: bidh unix sort a’ làimhseachadh caractaran ‘-’ (dash) mar nach fhaicear iad. Ann an ùine ghoirid, tha na teudan “a-b”, “aa”, “ac” air an òrdachadh mar “aa”, “a-b”, “ac”.

Tha am freagairt àbhaisteach anns a h-uile àite: cleachd locale a’ phrògramadair "C" agus bithidh tu toilichte. Feuch sinn:

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

Tha rudeigin air atharrachadh. Chaidh na Ivanovs suas san òrdugh cheart, ged a shleamhnaich Yolkina an àiteigin. Tillidh sinn chun duilgheadas tùsail:

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

Dh'obraich e gun mhearachdan, mar a gheall an eadar-lìon. Agus seo a dh'aindeoin Yolkina anns a 'chiad loidhne.

Tha e coltach gu bheil an duilgheadas air fhuasgladh, ach gun fhios nach feuch sinn còdachadh Ruiseanach eile - Windows CP1251:

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

Bidh an toradh seòrsachaidh, gu h-annasach gu leòr, aig an aon àm ris an sgìre "C", agus tha an eisimpleir gu lèir, a rèir sin, a 'ruith gun mhearachdan. Seòrsa de dhìomhaireachd.

Cha toil leam dìomhaireachd ann am prògramadh oir mar as trice bidh e a’ falach mhearachdan. Feumaidh sinn sgrùdadh domhainn a dhèanamh air mar a tha e ag obair. Deasaich agus dè a’ bhuaidh a th’ aige? LC_COLLATE .

Aig a’ cheann thall feuchaidh mi ri na ceistean a fhreagairt:

  • carson a chaidh sloinnidhean boireann a sheòrsachadh gu ceàrr?
  • carson LANG=ru_RU.CP1251 thionndaidh e a-mach gu bhith co-ionann LANG=C
  • carson Deasaich и còmhla beachdan eadar-dhealaichte mu òrdugh nan teudan air an òrdachadh
  • carson a tha mearachdan anns na h-eisimpleirean agam uile?
  • mu dheireadh mar a rèiticheas tu sreangan mar a thogras tu

A’ rèiteachadh ann an Unicode

Is e aithisg theicnigeach Àireamh 10 leis a’ chiad stad Algorithm cruinneachaidh Unicode Online unicode.org. Tha tòrr mion-fhiosrachaidh theicnigeach san aithisg, mar sin leig dhomh geàrr-chunntas goirid a thoirt seachad air na prìomh bheachdan.

coimeasadh - Tha sreangan “coimeas” mar bhunait airson algairim seòrsachaidh sam bith. Faodaidh na h-algorithms iad fhèin a bhith eadar-dhealaichte ("builgean", "co-aonadh", "luath"), ach cleachdaidh iad uile coimeas eadar paidhir shreathan gus an òrdugh anns a bheil iad a' nochdadh a dhearbhadh.

'S e duilgheadas caran toinnte a th' ann a bhith a' seòrsachadh teudan ann an cànan nàdarrach. Fiù ‘s anns na còdachadh aon-byte as sìmplidh, cha bhith òrdugh litrichean san aibideil, eadhon ann an dòigh air choreigin eadar-dhealaichte bhon aibideil Laideann Beurla, a’ dol aig an aon àm ri òrdugh nan luachan àireamhach leis a bheil na litrichean sin air an còdachadh. Mar sin anns an aibidil Ghearmailteach an litir Ö a' seasamh eadar О и P, agus anns a’ chòdachadh CP850 gheibh i eadar ÿ и Ü.

Faodaidh tu feuchainn ri tarraing a-mach à còdachadh sònraichte agus beachdachadh air litrichean “air leth math” a tha air an rèiteachadh ann an òrdugh air choreigin, mar a tha air a dhèanamh ann an Unicode. Còdachadh UTF8, UTF16 no aon-byte KOI8-R (ma tha feum air fo-sheata cuibhrichte de Unicode) bheir e seachad diofar riochdachaidhean àireamhach de litrichean, ach thoir iomradh air na h-aon eileamaidean den chlàr bhunaiteach.

Tha e a 'tionndadh a-mach, eadhon ged a thogas sinn clàr samhla bhon toiseach, cha bhith e comasach dhuinn òrdugh samhla uile-choitcheann a shònrachadh dha. Ann an diofar aibideil nàiseanta a chleachdas na h-aon litrichean, faodaidh òrdugh nan litrichean sin a bhith eadar-dhealaichte. Mar eisimpleir, ann am Fraingis Æ air a mheas mar cheangal agus air a sheòrsachadh mar shreang AE. Ann an Nirribhidh Æ bithidh litir air leth, a tha air a suidheachadh an deigh Z. Air an t-slighe, a bharrachd air ligatures mar Æ Tha litrichean ann le grunn shamhlaidhean. Mar sin tha litir anns an aibidil Seiceach Ch, a sheasas eadar H и I.

A bharrachd air eadar-dhealachaidhean ann an aibideil, tha traidiseanan nàiseanta eile ann a bheir buaidh air an seòrsachadh. Gu sònraichte, tha a 'cheist ag èirigh: dè an òrdugh a bu chòir faclan anns a bheil litrichean mòra agus litrichean beaga nochdadh anns an fhaclair? Faodaidh cleachdadh comharran puingeachaidh buaidh a thoirt air seòrsachadh cuideachd. Ann an Spàinntis, bithear a’ cleachdadh comharra ceist gun tionndadh aig toiseach seantans ceasnachail (An toil leat ceòl?). Anns a’ chùis seo, tha e follaiseach nach bu chòir seantansan ceasnachail a bhith air an cruinneachadh ann am buidheann air leth taobh a-muigh na h-aibideil, ach ciamar a rèiticheas tu loidhnichean le comharran puingeachaidh eile?

Cha bhi mi a’ gabhail còmhnaidh air a bhith a’ rèiteach teudan ann an cànanan gu math eadar-dhealaichte bhon fheadhainn Eòrpach. Thoir an aire, ann an cànanan le stiùireadh sgrìobhaidh deas gu clì no mullach gu bonn, gu bheil caractaran ann an loidhnichean nas coltaiche air an stòradh ann an òrdugh leughaidh, agus gu bheil na dòighean aca fhèin aig eadhon siostaman sgrìobhaidh neo-aibideil airson loidhnichean òrdachadh caractar a rèir caractar. . Mar eisimpleir, faodar hieroglyphs òrdachadh le stoidhle (Iuchraichean caractaran Sìneach) no le fuaimneachadh. Gus a bhith onarach, chan eil beachd sam bith agam ciamar a bu chòir emojis a chuir air dòigh, ach faodaidh tu rudeigin a chruthachadh dhaibh cuideachd.

Stèidhichte air na feartan gu h-àrd, chaidh na riatanasan bunaiteach airson coimeas a dhèanamh eadar sreangan stèidhichte air clàran Unicode:

  • chan eil coimeas sreangan an urra ri suidheachadh nan caractaran sa chlàr còd;
  • tha sreathan de charactaran a tha a’ cruthachadh aon charactar air an lughdachadh gu cruth canonical (A + tha an cearcall gu h-àrd mar an ceudna Å);
  • Nuair a thathar a’ dèanamh coimeas eadar sreangan, thathas a’ beachdachadh air caractar ann an co-theacs an t-sreang agus, ma tha sin riatanach, air a chur còmhla ri a nàbaidhean ann an aon aonad coimeas (Ch ann an Seiceach) no air a roinn ann an grunn (Æ ann am Fraingis);
  • feumar a h-uile feart nàiseanta (aibideil, litrichean mòra / beaga, puingeachadh, òrdugh sgrìobhaidh seòrsaichean) a bhith air an rèiteachadh suas ri sònrachadh làimhe an òrduigh (emoji);
  • tha coimeas cudromach chan ann a-mhàin airson a sheòrsachadh, ach cuideachd ann an iomadh àite eile, mar eisimpleir airson raointean sreath a shònrachadh (cuir {A... z} a-steach bash);
  • bu chòir coimeas a dhèanamh gu math luath.

A bharrachd air an sin, chruthaich ùghdaran na h-aithisg feartan coimeas air nach bu chòir do luchd-leasachaidh algairim a bhith an urra:

  • cha bu chòir gum biodh feum aig an algairim coimeas air seata charactaran fa leth airson gach cànan (tha cànanan Ruiseanach is Ucràineach a’ roinn a’ mhòr-chuid de charactaran Cyrillic);
  • cha bu chòir don choimeas a bhith an urra ri òrdugh nan caractaran ann an clàran Unicode;
  • cha bu chòir cuideam sreang a bhith na fheart den t-sreang, oir faodaidh cuideaman eadar-dhealaichte a bhith aig an aon sreang ann an co-theacsan cultarach eadar-dhealaichte;
  • faodaidh cuideaman sreath atharrachadh nuair a thèid iad còmhla no sgoltadh (bho x < y chan eil e a 'leantainn sin xz < yz);
  • thathas a’ meas gu bheil sreangan eadar-dhealaichte aig a bheil na h-aon cuideaman co-ionann bho shealladh an algairim sheòrsachaidh. Tha e comasach òrdachadh a bharrachd de shreathan mar sin a thoirt a-steach, ach dh’ fhaodadh e coileanadh a lughdachadh;
  • Nuair a bhios tu a’ rèiteachadh a-rithist, faodar sreathan leis na h-aon cuideaman atharrachadh. Tha seasmhachd na sheilbh de algairim seòrsachaidh sònraichte, agus chan e seilbh algairim coimeas sreang (faic am paragraf roimhe);
  • Faodaidh riaghailtean seòrsachaidh atharrachadh thar ùine mar a bhios traidiseanan cultarach ag ùrachadh/ag atharrachadh.

Thathas cuideachd ag ràdh nach eil fios aig an algairim coimeas mu dheidhinn semantics nan teudan a thathar a’ giullachd. Mar sin, cha bu chòir teudan anns nach eil ach àireamhan a bhith air an coimeas mar àireamhan, agus ann an liostaichean ainmean Beurla tha an t-alt (Beatles, na).

Gus na riatanasan ainmichte gu lèir a shàsachadh, thathas a’ moladh algorithm seòrsachaidh bùird ioma-ìre (gu dearbh ceithir-ìre).

Roimhe sin, tha na caractaran san t-sreang air an lughdachadh gu cruth canonical agus air an cruinneachadh ann an aonadan coimeas. Tha grunn chuideaman air an toirt do gach aonad coimeas a rèir grunn ìrean coimeas. Tha cuideaman aonadan coimeas nan eileamaidean de sheataichean òrdaichte (sa chùis seo, àireamhan iomlan) a ghabhas coimeas airson barrachd no nas lugha. Ciall sònraichte AIGNEACHADH (0x0) a’ ciallachadh nach eil an aonad seo an sàs anns a’ choimeas aig an ìre coimeas iomchaidh. Faodar coimeas sreangan ath-aithris grunn thursan, a’ cleachdadh cuideaman nan ìrean co-fhreagarrach. Aig gach ìre, tha cuideaman nan aonadan coimeas de dhà shreath air an coimeas ann an sreath ri chèile.

Ann an diofar bhuileachadh an algairim airson traidiseanan nàiseanta eadar-dhealaichte, faodaidh luachan nan co-èifeachdan a bhith eadar-dhealaichte, ach tha inbhe Unicode a’ toirt a-steach clàr bunaiteach de chuideaman - "Clàr Element Co-chruinneachadh Unicode bunaiteach" (DUCET). Bu mhath leam a thoirt fa-near gu bheil suidheachadh an caochlaideach LC_COLLATE dha-rìribh na chomharra air taghadh a’ chlàr cuideam anns a’ ghnìomh coimeas sreang.

Co-èifeachdan cuideam DUCET air a chur air dòigh mar a leanas:

  • aig a ‘chiad ìre, tha a h-uile litir air a lughdachadh chun aon chùis, tha diacritics air an toirt air falbh, tha comharran puingeachaidh (chan eil iad uile) air an leigeil seachad;
  • aig an dàrna ìre, chan eil ach diacritics air an toirt fa-near;
  • aig an treas ìre, chan eil ach cùis air a ghabhail a-steach;
  • aig a’ cheathramh ìre, chan eilear a’ toirt aire ach comharran puingeachaidh.

Bidh an coimeas a 'tachairt ann an grunn pasan: an toiseach, thathar a' dèanamh coimeas eadar co-èifeachdan a 'chiad ìre; ma tha na cuideaman aig an aon àm, thèid coimeas a dhèanamh a-rithist leis na cuideaman dàrna ìre; an uairsin is dòcha an treas agus an ceathramh.

Bidh an coimeas a’ tighinn gu crìch nuair a tha aonadan co-chosmhail ri diofar chuideaman anns na sreathan. Thathas den bheachd gu bheil sreathan aig a bheil cuideaman co-ionann aig na ceithir ìrean co-ionann ri chèile.

Thug an algairim seo (le dòrlach de mhion-fhiosrachadh teicnigeach a bharrachd) an t-ainm airson aithris Àireamh 10 - "Algorithm Co-chruinneachadh Unicode" (ACU).

Seo far a bheil an giùlan seòrsachaidh bhon eisimpleir againn a’ fàs beagan nas soilleire. Bhiodh e math a choimeas ri inbhe Unicode.

Gus deuchainn a dhèanamh air buileachadh ACU tha sònraichte ann ceisneachadh, a 'cleachdadh faidhle cuideaman, cur an gnìomh DUCET. Gheibh thu a h-uile seòrsa de rudan èibhinn anns an fhaidhle lannan. Mar eisimpleir, tha òrdugh mahjong agus dominoes Eòrpach, a bharrachd air òrdugh nan deiseachan ann an deic chairtean (samhla 1F000 agus nas fhaide). Tha na suidsichean cairt air an cur a rèir riaghailtean drochaid - PCBT, agus tha na cairtean anns an deise anns an t-sreath T, 2,3, XNUMX ... K.

Dèan sgrùdadh le làimh gu bheil sreathan air an òrdachadh gu ceart a rèir DUCET bhiodh e caran tedious, ach, gu fortanach dhuinne, tha deagh bhuileachadh air an leabharlann airson a bhith ag obair le Unicode - "Co-phàirtean eadar-nàiseanta airson Unicode"(ICU).

Air làrach-lìn an leabharlainn seo, air a leasachadh ann an IBM, tha duilleagan demo ann, nam measg duilleag algorithm coimeas sreang. Bidh sinn a’ dol a-steach do na loidhnichean deuchainn againn le roghainnean bunaiteach agus, feuch agus feuch, gheibh sinn rèiteachadh Ruiseanach foirfe.

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

Air an t-slighe, an làrach-lìn ICU Gheibh thu soilleireachadh air an algairim coimeas nuair a bhios tu a’ làimhseachadh comharran puingeachaidh. Ann an eisimpleirean Ceistean Cumanta cruinneachaidh tha an t-abstol agus an tàthan air an dearmad.

Chuidich Unicode sinn, ach coimhead airson adhbharan airson giùlan neònach Deasaich в Linux feumaidh a dhol a dh'àite eile.

Ag òrdachadh ann an glibc

Sealladh sgiobalta de na còdan stòr goireasach Deasaich bho GNU Core Utils sheall e, anns a’ ghoireas fhèin, gu bheil sgìreachadh a’ tighinn sìos gu bhith a’ clò-bhualadh luach làithreach a’ chaochladair LC_COLLATE nuair a bhios tu a’ ruith ann am modh deasbaid:

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

Bithear a’ dèanamh coimeasan sreang a’ cleachdadh a’ ghnìomh àbhaisteach strcoll, a tha a 'ciallachadh gu bheil a h-uile dad inntinneach anns an leabharlann glibc.

air a ' wiki pròiseact glibc coisrigte airson coimeas sreang aon pharagraf. Bhon pharagraf seo faodar a thuigsinn gu bheil ann an glibc tha an rèiteachadh stèidhichte air algorithm a tha aithnichte dhuinn mu thràth ACU (An algairim cruinneachaidh Unicode) agus/no aig ìre a tha faisg air ISO 14651 (Òrdachadh sreang eadar-nàiseanta agus coimeas). A thaobh an ìre as ùire, bu chòir a thoirt fa-near gur ann air an làrach inbhean.iso.org ISO 14651 air fhoillseachadh gu h-oifigeil gu poblach, ach tha an ceangal co-fhreagarrach a’ leantainn gu duilleag nach eil ann. Bidh Google a’ tilleadh grunn dhuilleagan le ceanglaichean gu làraich oifigeil a tha a’ tabhann leth-bhreac dealanach den inbhe a cheannach airson ceud iùro, ach air an treas no an ceathramh duilleag de thoraidhean rannsachaidh tha ceanglaichean dìreach ann cuideachd gu PDF. San fharsaingeachd, cha mhòr nach eil an ìre eadar-dhealaichte bho ACU, ach tha e nas dorra a leughadh leis nach eil eisimpleirean soilleir ann de fheartan nàiseanta de sheòrsachadh sreang.

Am fiosrachadh as inntinniche mu dheidhinn wiki bha ceangal ri lorgaire bug le deasbad air buileachadh coimeas sreang ann an glibc. Bhon deasbad faodar sin ionnsachadh glibc air a chleachdadh airson coimeas a dhèanamh eadar sreathan ISOclàr pearsanta An Clàr Teamplaid Coitcheann (CTT), agus gheibhear an seòladh san tagradh A àbhaisteach ISO 14651. Eadar 2000 agus 2015 tha an clàr seo a-steach glibc cha robh neach-gleidhidh aige agus bha e gu math eadar-dhealaichte (co-dhiù air an taobh a-muigh) bhon dreach làithreach den inbhe. Bho 2015 gu 2018, chaidh atharrachadh gu dreach ùr den chlàr a dhèanamh, agus a-nis tha cothrom agad coinneachadh ann am fìor bheatha dreach ùr den chlàr (CentOS 8), agus sean (CentOS 7).

A-nis gu bheil a h-uile fiosrachadh againn mun algairim agus clàran taiceil, is urrainn dhuinn tilleadh chun duilgheadas tùsail agus tuigsinn mar a rèiticheas tu sreangan gu ceart ann an locale na Ruis.

ISO 14651 / 14652

Còd stòr a’ bhùird anns a bheil ùidh againn CTT air a’ mhòr-chuid de sgaoilidhean Linux tha anns a’ chatalog /usr/share/i18n/locan/. Tha am bòrd fhèin anns an fhaidhle iso14651_t1_cumanta. An uairsin is e seo an stiùireadh faidhle dèan lethbhreac de iso14651_t1_common air a ghabhail a-steach san fhaidhle iso14651_t1, a tha, an uair sin, air a ghabhail a-steach ann am faidhlichean nàiseanta, a’ gabhail a-steach en_US и ru_RU. Air a 'mhòr-chuid de sgaoilidhean Linux tha na faidhlichean stòr uile air an toirt a-steach don stàladh bunaiteach, ach mura h-eil iad an làthair, feumaidh tu pasgan a bharrachd a chuir a-steach bhon sgaoileadh.

Structar faidhle iso14651_t1 is dòcha gu bheil e uamhasach briathrach, le riaghailtean neo-fhollaiseach airson ainmean a thogail, ach ma choimheadas tu air, tha a h-uile dad gu math sìmplidh. Tha an structar air a mhìneachadh anns an ìre àbhaisteach ISO 14652, agus faodar leth-bhreac dheth a luchdachadh sìos bhon làrach-lìn fosgailte-std.org. Faodar tuairisgeul eile air fòrmat an fhaidhle a leughadh ann sònrachaidhean POSIX от Buidheann Fosgailte. Mar dhòigh eile air an inbhe a leughadh, faodaidh tu còd stòr na gnìomh a sgrùdadh cruinnich_leugh в glibc/locale/programs/ld-collate.c.

Tha structar an fhaidhle a’ coimhead mar seo:

Gu gnàthach, tha an caractar air a chleachdadh mar charactar teicheadh, agus tha deireadh na loidhne às deidh a’ charactar # na bheachd. Faodar an dà shamhla ath-mhìneachadh, agus sin a dhèanamh anns an dreach ùr den chlàr:

escape_char /
comment_char %

Bidh comharran anns an fhaidhle san fhòrmat no (Càite x - figear hexadecimal). Is e seo an riochdachadh hexadecimal de phuingean còd Unicode anns a’ chòdachadh UCS-4 (UTF-32). A h-uile eileamaid eile ann an camagan ceàrn (a’ gabhail a-steach , <2> agus an leithid) air am meas mar cho-aontaran sreang sìmplidh aig nach eil mòran ciall taobh a-muigh a’ cho-theacsa.

Loidhne LC_COLLATE ag innse dhuinn gu bheil an ath rud a’ tòiseachadh an dàta a’ toirt cunntas air coimeas sreangan.

An toiseach, tha ainmean air an sònrachadh airson na cuideaman sa chlàr coimeas agus ainmean airson measgachadh nan samhlaidhean. San fharsaingeachd, buinidh an dà sheòrsa ainm do dhà bhuidheann eadar-dhealaichte, ach anns an fhìor fhaidhle tha iad measgaichte. Tha ainmean nan cuideaman air an sònrachadh leis a’ phrìomh fhacal tional-samhla (caractar coimeas) oir nuair a thathar a’ dèanamh coimeas, bithear a’ beachdachadh air caractaran Unicode aig a bheil na h-aon cuideaman mar charactaran co-ionann.

Tha fad iomlan na h-earrainn san ath-sgrùdadh faidhle gnàthach timcheall air 900 loidhne. Tharraing mi eisimpleirean bho ghrunn àiteachan gus neo-riaghailteachd ainmean agus grunn sheòrsaichean de cho-chòrdadh a nochdadh.

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-samhla a' clàradh sreang OSMANACH ann an clàr ainmean nan lannan
  • samhla cruinneachaidh .. a’ clàradh sreath ainmean anns a bheil ro-leasachan S agus iar-leasachan àireamhach hexadecimal bho 1D000 gu 1D 35F.
  • FFFF в tional-samhla tha e coltach ri àireamh mhòr gun ainm ann an hexadecimal, ach chan eil ann ach ainm a dh’ fhaodadh a bhith coltach
  • ainm a’ ciallachadh puing còd ann an còdachadh UCS-4
  • eileamaid cruinneachaidh o "" a’ clàradh ainm ùr airson paidhir dotagan Unicode.

Aon uair ‘s gu bheil ainmean nan cuideaman air am mìneachadh, tha na fìor chuideaman air an sònrachadh. Leis nach eil ach dàimhean nas motha na nas lugha cudromach an coimeas, tha na cuideaman air an suidheachadh le sreath sìmplidh de chlàradh ainmean. Tha na cuideaman “nas aotrom” air an liostadh an toiseach, agus an uairsin an fheadhainn “nas truime”. Leig leam do chuimhneachadh gu bheil ceithir cuideaman eadar-dhealaichte air gach caractar Unicode. An seo tha iad air an cur còmhla ann an aon sreath òrdaichte. Ann an teòiridh, dh’ fhaodadh ainm samhlachail sam bith a bhith air a chleachdadh aig gin de na ceithir ìrean, ach tha beachdan a’ nochdadh gu bheil an luchd-leasachaidh a’ sgaradh ainmean nan ìrean gu inntinn.

% 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

Mu dheireadh, an clàr cuideam fìor.

Tha an earrann cuideaman dùinte ann an loidhnichean prìomh fhacal òrdugh_tòisich и òrdugh_crìoch. Roghainnean a bharrachd òrdugh_tòisich co-dhùnadh dè an taobh a tha sreathan air an sganadh aig gach ìre coimeas. Tha an suidheachadh bunaiteach air adhart. Ann am bodhaig na h-earrainn tha loidhnichean anns a bheil an còd samhla agus na ceithir cuideaman aige. Faodaidh an còd caractar a bhith air a riochdachadh leis a 'charactar fhèin, puing còd, no ainm samhlachail a chaidh a mhìneachadh roimhe. Faodar cuideaman a thoirt cuideachd air ainmean samhlachail, puingean còd, no na samhlaidhean fhèin. Ma thèid puingean còd no caractaran a chleachdadh, tha an cuideam aca co-ionann ri luach àireamhach a’ phuing còd (suidheachadh sa chlàr Unicode). Thathas den bheachd gu bheil caractaran nach eil air an sònrachadh gu soilleir (mar a tha mi a’ tuigsinn) air an sònrachadh don chlàr le prìomh chuideam a tha a rèir an t-suidheachaidh ann an clàr Unicode. Luach cuideam sònraichte IGNORACH a’ ciallachadh gun tèid an samhla a leigeil seachad aig an ìre coimeas iomchaidh.

Gus structar nan lannan a nochdadh, thagh mi trì pìosan gu math follaiseach:

  • caractaran a tha gu tur air an dearmad
  • samhlaidhean co-ionann ris an àireamh a trì anns a’ chiad dà ìre
  • toiseach na h-aibidil Cyrillic, anns nach eil diacritics, agus mar sin air a rèiteachadh sa mhòr-chuid leis a 'chiad agus an treas ìre.

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

A-nis faodaidh tu tilleadh gu bhith a’ rèiteach nan eisimpleirean bho thoiseach an artaigil. Tha ambush na laighe sa phàirt seo den chlàr cuideam:

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

Chithear gu bheil sa chlàr seo na comharran puingeachaidh bhon chlàr ASCII (a’ gabhail a-steach àite) cha mhòr an-còmhnaidh air a leigeil seachad nuair a thathar a’ dèanamh coimeas eadar sreangan. Is e na h-aon eisgeachdan loidhnichean a tha a’ maidseadh anns a h-uile càil ach comharran puingeachaidh a lorgar ann an suidheachadh maidsidh. Tha na loidhnichean bhon eisimpleir agam (às deidh a sheòrsachadh) airson an algairim coimeas a’ coimhead mar seo:

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

Leis gu bheil anns a’ chlàr lannan, litrichean mòra ann an Ruisis a’ tighinn às deidh litrichean beaga (aig an treas ìre nas truime na ), tha an seòrsachadh a’ coimhead gu tur ceart.

Nuair a bhios tu a’ suidheachadh caochladair LC_COLLATE=C tha clàr sònraichte air a luchdachadh a tha a’ sònrachadh coimeas byte-by-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'
};

Leis gu bheil am puing còd Ё ann an Unicode a’ tighinn ro A, tha na sreangan air an òrdachadh a rèir sin.

Teacs agus clàran binary

Gu follaiseach, tha coimeas sreang mar obrachadh gu math cumanta, agus parsadh bùird CTT modh-obrach gu math daor. Gus an ruigsinneachd as fheàrr a thoirt don bhòrd, tha e air a chur ri chèile ann an cruth binary leis an àithne ionadaildef.

sgioba ionadaildef gabhail ri faidhle le clàr de fheartan nàiseanta (roghainn -i), anns a bheil a h-uile caractar air a riochdachadh le dotagan Unicode, agus faidhle conaltraidh eadar dotagan Unicode agus caractaran còdachadh sònraichte (roghainn -f). Mar thoradh air an obair, thèid faidhlichean binary a chruthachadh airson an locale leis an ainm a tha air a shònrachadh anns a’ pharamadair mu dheireadh.

Glib a’ toirt taic do dhà chruth faidhle binary: “traidiseanta” agus “ùr-nodha”.

Tha an cruth traidiseanta a’ ciallachadh gur e ainm an locale ainm an fho-eòlaire ann an /usr/lib/locale/. Bidh am fo-eòlaire seo a’ stòradh fhaidhlichean dà-chànanach LC_COLLATE, LC_CTYPE, LC_TIME Agus mar sin air adhart. Faidhle LC_IDENTIFICATION anns a bheil ainm foirmeil an locale (a dh’ fhaodadh a bhith eadar-dhealaichte bho ainm an eòlaire) agus beachdan.

Tha an cruth ùr-nodha a’ toirt a-steach stòradh a h-uile sgìre ann an aon tasglann /usr/lib/locale/locale-archive, a tha air a mhapadh gu cuimhne brìgheil a h-uile pròiseas a’ cleachdadh glibc. Tha an t-ainm locale anns a’ chruth ùr-nodha fo ùmhlachd beagan cananachaidh - chan eil ach àireamhan agus litrichean air an lughdachadh gu litrichean beaga air fhàgail anns na h-ainmean còdaidh. Mar sin ru_RU.KOI8-R, bithidh e air a shàbhaladh mar ru_RU.koi8r.

Bithear a’ sgrùdadh fhaidhlichean cuir a-steach san eòlaire gnàthach, a bharrachd air ann an clàran /usr/share/i18n/locan/ и /usr/share/i18n/charmaps/ airson faidhlichean CTT agus còdachadh fhaidhlichean, fa leth.

Mar eisimpleir, an àithne

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

cruinnichidh e am faidhle /usr/share/i18n/locales/ru_RU a’ cleachdadh faidhle còdaidh /usr/share/i18n/charmaps/MAC-CYRILLIC.gz agus sàbhail an toradh a-steach /usr/lib/locale/locale-archive fon ainm ru_RU.maccyrillic

Ma shuidhicheas tu an caochladair LANG = en_US.UTF-8 an uairsin glibc coimheadaidh e airson binaries locale anns an t-sreath de fhaidhlichean is chlàran a leanas:

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

Ma tha locale a’ tachairt an dà chuid ann an cruth traidiseanta agus ùr-nodha, tha prìomhachas ga thoirt don fhear ùr-nodha.

Chì thu an liosta de locales cruinnichte leis an àithne locale -a.

Ag ullachadh do bhòrd coimeas

A-nis, le armachd an eòlais, faodaidh tu an clàr coimeas sreang agad fhèin a chruthachadh. Bu chòir don chlàr seo coimeas ceart a dhèanamh eadar litrichean Ruiseanach, a 'gabhail a-steach an litir Ё, agus aig an aon àm aire a thoirt do chomharran puingeachaidh a rèir a' chlàr ASCII.

Tha dà ìre anns a’ phròiseas airson a’ bhòrd seòrsachaidh agad fhèin ullachadh: a’ deasachadh a’ chlàr cuideaman agus ga chur ri chèile ann an cruth binary leis an àithne ionadaildef.

Gus an tèid an clàr coimeas atharrachadh le glè bheag de chosgaisean deasachaidh, anns a’ chruth ISO 14652 Tha earrannan air an toirt seachad airson cuideaman clàr gnàthaichte atharrachadh. Bidh an earrann a’ tòiseachadh le prìomh fhacal ath-òrdachadh-às dèidh agus a’ comharrachadh an t-suidheachaidh às deidh an ath-chur a dhèanamh. Tha an earrann a’ crìochnachadh leis an loidhne ath-òrdachadh-crìoch. Ma tha feum air grunn earrannan den chlàr a cheartachadh, thèid earrann a chruthachadh airson gach earrann den leithid.

Rinn mi lethbhreac de dhreachan ùra de na faidhlichean iso14651_t1_cumanta и ru_RU bhon stòr glibc dhan eòlaire dachaigh agam ~/.local/share/i18n/locales/ agus dheasaich mi an earrann beagan LC_COLLATE в ru_RU. Tha dreachan ùra de fhaidhlichean gu tur co-chòrdail ris an dreach agam glibc. Ma tha thu airson tionndaidhean nas sine de fhaidhlichean a chleachdadh, feumaidh tu na h-ainmean samhlachail atharrachadh agus an t-àite far a bheil an t-àite a’ tòiseachadh sa chlàr.

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

Gu dearbh, bhiodh e riatanach na raointean atharrachadh LC_IDENTIFICATION gus an toir iad iomradh air an sgìre ru_MY, ach anns an eisimpleir agam cha robh feum air seo, oir chuir mi a-mach an tasglann bhon rannsachadh airson locales locale-tasglann.

gu bheil ionadaildef dh’ obraich mi le faidhlichean sa phasgan agam tro chaochladair I18NPATH Faodaidh tu eòlaire a bharrachd a chuir ris gus faidhlichean cuir a-steach a lorg, agus faodar an eòlaire gus faidhlichean binary a shàbhaladh a shònrachadh mar shlighe le slashes:

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

POSIX a' gabhail ris gu bheil ann an CÀNAIN faodaidh tu slighean iomlan a sgrìobhadh gu clàran le faidhlichean locale, a’ tòiseachadh le slash air adhart, ach glibc в Linux tha a h-uile slighe air a chunntadh bhon eòlaire bunaiteach, a dh'fhaodar a thoirt thairis tro chaochladair LOCPATH. Às deidh an stàladh LOCPATH=~/.local/lib/locale/ thèid a h-uile faidhle co-cheangailte ri sgìreachadh a sgrùdadh sa phasgan agam a-mhàin. Tasglann de locales leis an t-seata caochlaideach LOCPATH air an dearmad.

Seo an deuchainn chinnteach:

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

Hooray! Rinn sinn e!

Obraich mu bhiastagan

Tha mi air na ceistean mu sheòrsachadh sreang a fhreagairt aig an toiseach mu thràth, ach tha ceist no dhà ann fhathast mu mhearachdan - faicsinneach agus do-fhaicsinneach.

Tillidh sinn chun duilgheadas tùsail.

Agus am prògram Deasaich agus prògram còmhla cleachd na h-aon gnìomhan coimeas sreang bho glibc. Ciamar a thachair sin còmhla thug e mearachd seòrsachaidh air sreathan a chaidh a rèiteachadh leis an àithne Deasaich anns an sgìre ga_US.UTF-8? Tha am freagairt sìmplidh: Deasaich coimeas a dhèanamh eadar an t-sreath gu lèir, agus còmhla coimeas a dhèanamh eadar an iuchair a-mhàin, a tha gu bunaiteach mar thoiseach na sreang suas chun chiad charactar àite geal. Anns an eisimpleir agam, dh’ adhbhraich seo teachdaireachd-mearachd leis nach robh seòrsachadh a’ chiad fhaclan anns na loidhnichean a’ freagairt ri seòrsachadh nan loidhnichean slàn.

Ionadail "C" a’ gealltainn ann an teudan eagraichte gun tèid na fo-thiotalan tùsail suas chun chiad àite a sheòrsachadh cuideachd, ach chan eil seo ach a’ falach na mearachd. Tha e comasach dàta a thaghadh (daoine leis na h-aon sloinnidhean, ach ciad ainmean eadar-dhealaichte) a bheireadh toradh co-aonaidh ceàrr às aonais an teachdaireachd mearachd. Ma tha sinn ag iarraidh còmhla loidhnichean faidhle aonaichte le làn ainm, is e an dòigh cheart a bhith a’ sònrachadh gu soilleir an dealaiche achaidh agus a sheòrsachadh a rèir a’ phrìomh raon, agus chan ann leis an loidhne gu lèir. Anns a 'chùis seo, thèid an aonachadh air adhart gu ceart agus cha bhi mearachdan ann an locale sam bith:

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

Eisimpleir air a chuir gu bàs gu soirbheachail ann an còdachadh CP1251 tha mearachd eile ann. Is e an fhìrinn gu bheil anns a h-uile sgaoileadh as aithne dhomh Linux tha pasganan ionadail a dhìth ru_RU.CP1251. Mura lorgar an locale cruinnichte, an uairsin Deasaich gu sàmhach a’ cleachdadh coimeas byte-by-byte, is e sin a chunnaic sinn.

Air an t-slighe, tha glitch bheag eile ann co-cheangailte ri ruigsinneachd nan sgìrean cruinnichte. Sgioba LOCPATH =/tmp locale -a bheir e seachad liosta de na h-àiteachan air fad ann locale-tasglann, ach leis an t-seata caochlaideach LOCPATH airson a h-uile prògram (a’ gabhail a-steach a’ mhòr-chuid locale) cha bhi na h-ionadan sin rim faighinn.

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

co-dhùnadh

Ma tha thu nad phrògramadair a tha cleachdte ri bhith a’ smaoineachadh gur e seata de bytes a th’ ann an teudan, is e sin do roghainn LC_COLLATE=C.

Mas e cànanaiche no neach-cruinneachaidh faclair a th’ annad, ’s fheàrr dhut cruinneachadh a dhèanamh san sgìre agad.

Ma tha thu nad neach-cleachdaidh sìmplidh, feumaidh tu dìreach fàs cleachdte ris an fhìrinn gu bheil an àithne ls -a toraidhean a’ tòiseachadh le dot measgaichte le faidhlichean a’ tòiseachadh le litir, agus Comanndair meadhan oidhche, a chleachdas na gnìomhan a-staigh aige gus ainmean a sheòrsachadh, a’ cur faidhlichean a’ tòiseachadh le dot aig toiseach na liosta.

iomraidhean

Aithisg Àireamh 10 Unicode algairim cruinneachaidh

Cuideaman charactaran aig unicode.org

ICU - cur an gnìomh leabharlann airson obrachadh le Unicode bho IBM.

Deasachadh deuchainn a 'cleachdadh ICU

Caractar cuideam ann an ISO 14651

Tuairisgeul air fòrmat an fhaidhle le lannan ISO 14652

Còmhradh air coimeas sreang ann an glibc

Source: www.habr.com

Cuir beachd ann