ケヌスケヌストゥルヌスプログラマヌは知っおおくべき

で、ノヌスベむのPython䌚議2018で、私が䞎えた話のナヌザヌ名にしたす。レポヌトからの情報のほずんどは、django-registrationをサポヌトしおきた12幎以䞊にわたっお私が収集したものです。この経隓は、私が蚈画しおいたよりもはるかに倚くの知識を私に䞎えおくれたした。



しかし、私の話の冒頭で、これは䞀連の「プログラマヌが信じおいるXに぀いおの誀解」からの別の露出ではないこずを述べたした。あなたはそのような啓瀺をいく぀でも芋぀けるこずができたす。しかし、私はこれらの蚘事が奜きではありたせん。圌らはおそらく間違っおいるず思われるさたざたなこずをリストしおいたすが、これがなぜであり、代わりに䜕をすべきかを説明するこずはめったにありたせん。人々はこのような蚘事を読んで、この成果を祝犏し、これらの蚘事に蚘茉されおいない間違いを犯すための興味深い新しい方法を芋぀けに行くのではないかず思いたす。これは、これらの゚ラヌの原因ずなっおいる問題を実際に理解しおいなかったためです。



したがっお、私のレポヌトでは、いく぀かの問題を可胜な限り説明し、それらを解決する方法を説明しようずしたした-私はこのアプロヌチがはるかに奜きです。通過するずきに觊れただけのトピックの1぀1぀のスラむドず他のスラむドでのいく぀かの蚀及は、キャラクタヌの堎合に関連する可胜性のある耇雑さです。私が議論した問題倧文字ず小文字を区別しない識別子の比范に察する公匏のCorrect Answer™があり、講挔では、Python暙準ラむブラリのみを䜿甚するこずで私が知っおいる最善の解決策を瀺したした。



ただし、Unicodeの堎合のより深い耇雑さに぀いお簡単に説明したので、詳现に぀いおは少し時間を割いお説明したいず思いたす。これは興味深いこずであり、それを理解するこずは、テキスト凊理コヌドを蚭蚈および䜜成する際の決定に圹立ちたす。したがっお、「プログラマヌが信じるXに぀いおの誀解」、「プログラマヌが知っおおくべき真実」ずいう蚘事の反察を提䟛したす。



そしおもう1぀、Unicodeには甚語がたくさんありたす。この蚘事では、Unicode暙準であるため、䞻に「倧文字」ず「小文字」の定矩を䜿甚したす。これらの甚語を䜿甚したす。小文字/倧文字のような他の甚語が奜きなら、それは問題ありたせん。たた、私はよく「シンボル」ずいう甚語を䜿甚したすが、これは間違っおいるず感じる人もいたす。はい、Unicodeでは、「文字」の抂念は必ずしも人々が期埅するものではないため、他の甚語を䜿甚しお回避するのが最善の堎合がよくありたす。ただし、この蚘事では、Unicodeで䜿甚されおいる甚語を䜿甚しお、䞻匵できる抜象的な゚ンティティを説明したす。重芁な堎合は垞に、コヌドポむントなどのより具䜓的な甚語を䜿甚しお明確にしたす。



3぀以䞊のレゞスタがありたす



ペヌロッパの蚀語のネむティブスピヌカヌは、圌らの蚀語が特定のこずを瀺すために倧文字ず小文字を䜿甚するずいう事実に慣れおいたす。たずえば、英語[およびロシア語]の蚀語では、通垞、文は倧文字で始たり、ほずんどの堎合小文字で続きたす。たた、固有名詞は倧文字で始たり、倚くの略語や略語は倧文字で曞かれおいたす。



そしお、私たちは通垞、レゞスタヌは2぀しかないず考えおいたす。文字「A」ず文字「a」がありたす。 1぀は倧文字、もう1぀は小文字です-そうではありたせんか



ただし、Unicodeには3぀のレゞスタがありたす。倧文字、小文字、タむトルケヌス[titlecase]がありたす。英語では、名前はこのように曞かれおいたす。たずえば、「アベンゞャヌズむンフィニティりォヌ」。通垞、この堎合、各単語の最初の文字は単玔に倧文字で蚘述されたすたた、さたざたなルヌルやスタむルによっおは、蚘事などの䞀郚の単語は倧文字になりたせん。



Unicode暙準では、倧文字の文字の䟋を瀺しおいたす。U+ 01F2 LATIN CAPITAL LETTER D WITH SMALLZ。次のようになりたすDz。



このような文字は、Unicode暙準の最も初期の゜リュヌションの1぀である既存のテキスト゚ンコヌディングずの䞋䜍互換性の悪圱響を凊理するために必芁になる堎合がありたす。 Unicodeは、暙準の文字の組み合わせを䜿甚しおシヌケンスを䜜成する方が䟿利です。ただし、倚くの既存のシステムでは、既補のシヌケンス甚にスペヌスがすでに割り圓おられおいたす。たずえば、ISO-8859-1 "latin-1"では、 "é"文字の番号は0xe9の既補のフォヌムです。 Unicodeでは、この文字を別の「e」ずアクセントマヌクで曞くこずが望たしいでしょう。ただし、latin-1などの既存の゚ンコヌディングずの完党な䞋䜍互換性を確保するために、Unicodeは既補の文字にコヌドポむントも割り圓おたす。たずえば、U + 00E9 LATIN SMALL LETTER E WITHACUTE。



この文字のコヌド䜍眮はそのlatin-1バむト倀ず同じですが、これに䟝存しないでください。Unicodeでの文字゚ンコヌドがこれらの䜍眮を保持する可胜性は䜎いです。たずえば、UTF-8では、コヌド䜍眮U + 00E9はバむトシヌケンス0xc30xa9ずしお曞き蟌たれたす。



そしおもちろん、既存の゚ンコヌディングには倧文字を䜿甚するずきに特別な凊理が必芁な文字がありたす。そのため、それらは「そのたた」Unicodeに含たれおいたした。それらを確認したい堎合は、お気に入りのUnicodeデヌタベヌスでLtカテゎリ「レタヌ、タむトルケヌス」の文字を怜玢しおください。



ケヌスを定矩する方法はいく぀かありたす



Unicode暙準§4.2には、3぀の異なるケヌス定矩がリストされおいたす。おそらく、3぀のうちの1぀を遞択するのは、プログラミング蚀語によっお行われたす。それ以倖の堎合、遞択は特定の目暙によっお異なりたす。これらの定矩は次のずおりです。

  1. 文字は、Luカテゎリ「文字、倧文字」の堎合は倧文字で、Llカテゎリ「文字、小文字」の堎合は小文字です。この芏栌は、この定矩の制限を認識しおいたす。特定の各シンボルは、カテゎリの1぀にのみ垰属する必芁がありたす。このため、倧文字たたは小文字で「必須」である倚くの文字は、他のカテゎリに属しおいるため、この芁件を満たしたせん。
  2. 文字は、Uppercaseプロパティを継承する堎合は倧文字になり、Lowercaseプロパティを継承する堎合は小文字になりたす。これは、1぀の定矩ず他の文字プロパティの組み合わせであり、倧文字ず小文字が含たれる堎合がありたす。
  3. 倧文字にマップされた埌も倉曎されない堎合、文字は倧文字になりたす。小文字にマッピングされた埌も倉曎されない堎合、文字は小文字になりたす。これはかなり䞀般的な定矩ですが、盎感的ではない動䜜をするこずもありたす。




シンボルの限られたサブセット具䜓的には文字を䜿甚しおいる堎合は、1぀の定矩で十分な堎合がありたす。レパヌトリヌがより広い堎合文字ではない文字のような蚘号が含たれおいる堎合、2番目の定矩が適しおいる可胜性がありたす。Unicode暙準§4.2で掚奚されおいたす。

Unicode文字列を操䜜するプログラマヌは、文字プロパティを盎接操䜜しない堎合は、isLowerCaseおよびその機胜的ないずこtoLowerCaseなどの文字列関数を操䜜する必芁がありたす。




ここで蚀及されおいる機胜は、Unicode暙準の§3.13で定矩されおいたす。正匏には、定矩3は§3.13のisLowerCase関数ずisUpperCase関数を䜿甚し、それぞれtoLowerCaseずtoUpperCaseの固定䜍眮で定矩されおいたす。



プログラミング蚀語に文字列たたは個々の文字の倧文字ず小文字をチェックたたは倉換する機胜がある堎合は、䞊蚘の定矩のどれが実装で䜿甚されおいるかを調べる䟡倀がありたす。興味があれば、Pythonのisupperメ゜ッドずislowerメ゜ッドは2番目の定矩を䜿甚したす。



キャラクタヌの堎合をその倖芳や名前で理解するこずは䞍可胜です



倚くのキャラクタヌの登堎により、どのような堎合かがわかりたす。たずえば、「A」は倧文字です。これは、シンボルの名前「LATIN CAPITALLETTERA」からも明らかです。ただし、この方法が機胜しない堎合がありたす。コヌドポむントU + 1D34を取りたす。次のようになりたすᎎ。Unicodeでは、次の名前が割り圓おられたすMODIFIER LETTER CAPITAL H.では、倧文字ですよね



実際、小文字のプロパティを継承しおいるため、定矩2では、芖芚的に倧文字のHに䌌おおり、名前に「CAPITAL」ずいう単語が含たれおいるにもかかわらず、小文字になっおいたす。



䞀郚の文字はたったく倧文字ず小文字を区別したせん



Unicode暙準の§3.13の定矩135は次のように述べおいたす。

Cに小文字たたは倧文字のプロパティがある堎合、たたはGeneral_CategoryがTitlecase_Letterである堎合に限り、Cは倧文字ず小文字を区別したす。




これは、倚くのUnicode文字実際には、それらのほずんどが倧文字ず小文字を区別しないこずを意味したす。圌らの事件に぀いおの質問は意味がなく、事件の倉曎は圌らに圱響を䞎えたせん。ただし、定矩3により、この質問に察する答えを埗るこずができたす。



䞀郚の文字は、耇数のレゞスタがあるように動䜜したす



぀たり、定矩3を䜿甚しお、倧文字ず小文字を区別しない文字が倧文字であるか小文字であるかを尋ねるず、「はい」ずいう答えが埗られたす。



Unicode暙準は、文字U + 02BD MODIFIER LETTER REVERSED COMMA次のようになりたす ʜの䟋衚4-1、7行目を瀺しおいたす。継承された小文字たたは倧文字のプロパティがなく、Ltカテゎリに属しおいないため、倧文字ず小文字は区別されたせん。同時に、倧文字に倉換しおも倉曎されず、小文字に倉換しおも倉曎されないため、3番目の定矩によれば、「あなたは倧文字に属したすか」ずいう䞡方の質問に「はい」ず答えたす。ず「あなたは小文字ですか」



これは䞍必芁な混乱を匕き起こす可胜性があるようですが、芁点は、定矩3がUnicode文字の任意のシヌケンスで機胜し、倧文字ず小文字の倉換アルゎリズムを単玔化できるこずです倧文字ず小文字を区別しない文字はそのたたになりたす。



ケヌスは状況に応じお異なりたす



Unicodeケヌス倉換テヌブルがすべおの文字をカバヌしおいる堎合、この倉換は単にテヌブル内の適切な堎所を芋぀けるこずであるず考えるかもしれたせん。たずえば、Unicodeデヌタベヌスには、U + 0041 LATIN CAPITAL LETTERAは小文字のU + 0061 LATIN SMALL LETTER Aず蚘茉されおいたす。単玔ですね。



このアプロヌチが機胜しない1぀の䟋は、ギリシャ語です。文字Σ぀たり、U + 03A3 GREEK CAPITAL LETTER SIGMAは、単語のどこにあるかに応じお、小文字に倉換されるず2぀の異なる文字にマップされたす。単語の終わりにある堎合は、小文字のσU + 03C2 GREEK SMALL LETTER FINAL SIGMAになりたす。他の堎所ではσU + 03C3 GREEK SMALL LETTER SIGMAになりたす。



これは、レゞスタが1察1たたは䞀時的ではないこずを意味したす。別の䟋はßU + 00DF LATIN SMALL LETTER SHARP S、たたはescetです。別の倧文字の圢匏ẞ、U + 1E9E LATIN CAPITAL LETTER SHARP Sがありたすが、倧文字は「SS」になりたす。たた、「SS」を小文字に倉換するず「ss」になりたす。したがっお倧文字ず小文字の倉換にUnicodeの甚語を䜿甚toLowerCasetoUpperCaseß= Ss。



ケヌスはロケヌルに䟝存したす



蚀語が異なれば、倧文字ず小文字の倉換ルヌルも異なりたす。最も䞀般的な䟋iU + 0069 LATIN SMALL LETTER IずIU + 0049 LATIN CAPITAL LETTER Iは、ほずんどのロケヌルで盞互に倉換されたす。すべおではありたせんが、ほずんどです。ロケヌルazおよびtrトルコ語では、倧文字のiはİU + 0130 LATIN CAPITAL LETTER I WITH DOT ABOVEになり、小文字のIはıU + 0131 LATIN SMALL LETTER DOTLESS Iになりたす。時々、それを正しくするこずは本圓に生ず死の違いを意味したす。



Unicode自䜓が、すべおのロケヌルで考えられるすべおの倧文字小文字倉換ルヌルを凊理するわけではありたせん。 Unicodeデヌタベヌスには、ロケヌルに固有ではなく、すべおの文字を倉換するための䞀般的なルヌルのみがありたす。たた、いく぀かの蚀語ず耇合圢匏には特別な芏則がありたす-リトアニア語、トルコ語、ギリシャ語のいく぀かの機胜。他のすべおはそこにありたせん。芏栌の§3.13はこれに蚀及しおおり、必芁に応じおロケヌル固有の倉換ルヌルの導入を掚奚しおいたす。



䞀䟋は英語を話すサむンです-これは特定の名前のタむトルケヌスです。 「O'brian」は「O'brian」に倉換する必芁がありたす「O'brian」ではありたせん。ただし、その際、「It's」は「It'S」ではなく「It's」に倉換する必芁がありたす。 Unicodeで凊理されない別の䟋は、オランダ語の文字の組み合わせ「ij」です。これは、タむトルケヌスに倉換するずきに、単語の先頭にある堎合はすべお倧文字に倉換する必芁がありたす。したがっお、タむトルレゞスタのオランダで最倧のベむは、「Ijsselmeer」ではなく「IJsselmeer」になりたす。 Unicodeには、必芁に応じお、IJU+ 0132 LATIN CAPITAL LIGATUREIJおよびijU+ 0133 LATIN SMALL LIGATUREIJの文字がありたす。デフォルトでは、ケヌス倉換はそれらを盞互に倉換したすただし、互換性の同等性を䜿甚するUnicode正芏化フォヌムはそれらを2぀の別々の文字に分割したす。





レポヌトに瀺されおいる資料に戻りたす。 Unicodeの倧文字小文字管理は耇雑であるため、倚くのプログラミング蚀語に芋られる暙準の小文字たたは倧文字の倉換関数を䜿甚しお、倧文字ず小文字を区別しない比范を実行するこずはできたせん。このような比范のために、Unicodeには倧文字ず小文字の区別の抂念があり、暙準の§3.13はtoCaseFold関数ずisCaseFolded関数を定矩しおいたす。



折りたたたれたケヌスぞのキャストは小文字ぞのキャストに䌌おいるず思うかもしれたせんが、そうではありたせん。 Unicode暙準では、倧文字ず小文字を区別する文字列を小文字にする必芁はないず譊告しおいたす。䟋ずしお、チェロキヌ蚀語が䞎えられおいたす-そこで、折りたたたれた倧文字小文字の文字列では、倧文字の文字も出くわしたす。



私の講挔のスラむドの1぀では、Unicodeテクニカルレポヌト36が可胜な限りPythonで完党に実装されおいたす。 NFKC正芏化が実行され、結果の文字列に察しおcasefoldメ゜ッドPython 3以降でのみ䜿甚可胜が呌び出されたす。それでも、䞀郚の゚ッゞケヌスは倱敗し、それはID比范に掚奚されるものではありたせん。最初の悪いニュヌスPythonは、XID_StartたたはXID_Continueにない文字、たたはDefault_Ignorable_Code_Pointプロパティを持぀文字を陀倖するのに十分なUnicodeプロパティを公開しおいたせん。私の知る限り、NFKC_Casefoldマッピングはサポヌトされおいたせん。倉曎されたNFKCUAX31§5.1を䜿甚する簡単な方法もありたせん。



幞いなこずに、これらの゚ッゞケヌスのほずんどには、問題のシンボルによっおもたらされる実際のセキュリティリスクは含たれおいたせん。たた、ケヌスフォヌルディングは、原則ずしお正芏化保存操䜜ずしお定矩されおいたせんしたがっお、ケヌスフォヌルディング埌にNFCに再正芏化されるNFKC_Casefoldマッピング。䞀般に、比范する堎合、前凊理埌に䞡方の文字列が正芏化されおいるかどうかは関係ありたせん。前凊理に䞀貫性がないかどうか、および埌で「異なるはず」の行のみが埌で異なるこずが保蚌されるかどうかを気にしたす。これが心配な堎合は、レゞスタの远加埌に手動で再正芏化できたす。



今のずころ十分です



この蚘事は、前のレポヌトず同様に網矅的ではなく、このすべおの資料を1぀の投皿に収めるこずはほずんど䞍可胜です。これがこのトピックの耇雑さの有甚な抂芁であり、さらなる情報を探すのに十分な出発点を提䟛するこずを願っおいたす。したがっお、原則ずしおここで停止できたす。



他の人が䞀連の「プログラマヌが信じるXに぀いおの誀解」からの露出を曞くのをやめお、「プログラマヌが知っおおくべき真実」のような蚘事を曞き始めるこずを期埅するのは単玔ではないでしょうか。



All Articles