Ez egy nagy témakör! Lehetne róla vaskos könyvet írni, és többen meg is tették (keress rá az Amazonon a „unicode book” kifejezésre, hogy láss néhány példát).
A számítógépes karakterkezelés sokkal egyszerűbb volt a korábbi évtizedekben, amikor a programozók azt feltételezték, hogy az angol az egyetlen fontos nyelv. Tehát: 26 betű kis- és nagybetűvel, 10 számjegy, néhány írásjel, valamint egy kód (0x07) a csengő megszólaltatásához, és mindez belefért 7 bitbe: ez az ASCII karakterkészlet.
Természetesen az emberek elkezdték kérdezni, mi van az à, ä és Ł karakterekkel, aztán mások azt kérdezték, mi van az ऄ, ஹ és ญ karakterekkel, a fiatalok pedig emojikat akartak 😱. Mit lehet ilyenkor tenni?
Hogy rövidre fogjam: sok okos és türelmes embernek évekig kellett bizottságokban dolgoznia, hogy kidolgozza a Unicode karakterkészlet és az olyan kódolások, mint a UTF-8 részleteit, ráadásul rengeteg szoftvert kellett nagyon bonyolultan átírni. Emellett rengeteg új hiba is keletkezett.
Hogy ne minden törjön el, a Unicode/UTF-8 kialakítása biztosítja, hogy az első 127 kód megegyezzen az ASCII-val (még a csengő is).
A nagyjából 2005 után tervezett nyelvek óriási előnye, hogy addigra már létezett egy viszonylag stabil Unicode-szabvány.
A Julia (amely 2012-ben jelent meg először) abból indulhatott ki, hogy minden Unicode lesz: a karakterek, a stringek, a változó- és függvénynevek, a matematikai operátorok...
A kézikönyvet idézve: „A Julia egyszerűvé és hatékonnyá teszi a sima ASCII-szövegek kezelését, a Unicode kezelése pedig a lehető legegyszerűbb és leghatékonyabb.” Figyeld meg a »a lehető« kifejezést, ez a kijelentés fontos része.
A karakterliterálokat szimpla idézőjelbe írjuk, és különböznek a dupla idézőjelbe írt stringektől.
Ez magától értetődő a C/C++ világából érkezőknek, de a Python- és JavaScript-programozóknak zavaró lehet.
julia> a = 'a' # Roman alphabet
'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)
julia> typeof(a)
Char
julia> jha = 'झ' # Devanagari alphabet
'झ': Unicode U+091D (category Lo: Letter, other)
julia> typeof(jha)
Char
julia> '❤' # heart emoji
'❤': Unicode U+2764 (category So: Symbol, other)
A példákból láthatjuk, hogy a típus Char, és a Julia további információt is ad a karakter kategóriájáról.
Ha jobban megnézzük, úgy tűnik, hogy ezek a karakterek 4 hexadecimális számjeggyel ábrázolhatók. A teljes karakterkészlethez akár 6 hexadecimális számjegy is kell.
Ezeket a számokat „kódpontoknak” nevezzük, és jelenleg az U+0000-tól az U+10FFFF-ig terjednek.
A REPL-ben megjelennek, de a kódban a codepoints() függvénnyel kérheted le őket.
A Char és az Int közötti átalakítás egyszerű:
julia> Int('a')
97
julia> Char(97)
'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)
A fordító a Char típuson az egészszám-aritmetika néhány formáját engedélyezi:
julia> 'b' - 'a' # interval, in alphabetic order
1
julia> 'b' + 'a'
ERROR: MethodError: no method matching +(::Char, ::Char)
julia> 'a' + 5
'f': ASCII/Unicode U+0066 (category Ll: Letter, lowercase)
julia> 'f' + ('A' - 'a') # same as `uppercase('f')`
'F': ASCII/Unicode U+0046 (category Lu: Letter, uppercase)
Sok stringkezelő függvény Char bemeneten is működik.
uppercase() és a lowercase() függvénnyel.isuppercase() és az islowercase() függvénnyel ellenőrizheted.isletter() sok ábécét lefedisdigit(), szigorúan a 0:9 tartományt vizsgáljaisnumeric(), a isdigit-nél tágabb, így ¾ esetén is true, és számos nem európai írásrendszerre is igazisxdigit(), hexadecimális számjegyekisascii(), Unicode előtti karakterispunct(), írásjelekisspace(), bármely whitespace-karakterisprint(), nyomtatható karakterek (ellentéte az iscntrl())islowercase('A') # false
uppercase('γ') # 'Γ': Unicode U+0393 (category Lu: Letter, uppercase)
ispunct('@') # true
isdigit('A') # false
isxdigit('A') # true
Stringből Char vektorba a collect() függvénnyel juthatunk.
Char vektorból stringbe a String() konstruktorral juthatunk.
julia> s = "abcde"
"abcde"
julia> cv = collect(s)
5-element Vector{Char}:
'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)
'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)
'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)
'd': ASCII/Unicode U+0064 (category Ll: Letter, lowercase)
'e': ASCII/Unicode U+0065 (category Ll: Letter, lowercase)
julia> String(cv)
"abcde"
Ez bármilyen karakterrel működik, nem csak ASCII-vel.
julia> collect("❤,😱")
3-element Vector{Char}:
'❤': Unicode U+2764 (category So: Symbol, other)
',': ASCII/Unicode U+002C (category Po: Punctuation, other)
'😱': Unicode U+1F631 (category So: Symbol, other)
Vedd figyelembe, hogy a String() konstruktor egy vektoron működik.
Ha egyetlen Char-t szeretnél átalakítani egykarakteres stringgé, akkor a string() függvényt kell használnod, kisbetűs s-sel.
julia> string('a')
"a"
Az eddigiek viszonylag egyszerűnek tűnnek, tényleg nincs miért aggódni?
Sajnos ez túl optimista!
Az egyik bonyodalom abból fakad, hogy kódpontonként „akár” 6 hexadecimális számjegyre is szükség lehet. Ez azt jelenti, hogy a különböző karakterek UTF-8 kódolás esetén különböző mennyiségű memóriát igényelnek.
Egy byte csak 255-ig tud (előjel nélküli) számokat tárolni, ami két hexadecimális számjegy, ezért a UTF-8 változó számú byte-ot (1-től 4-ig) használ egy Char tárolására.
Ezeket „kódegységeknek” nevezzük, és a ncodeunits() függvény megadja, mennyi kell egy adott karakterhez.
julia> codepoint(jha) # jha 'झ' is defined in an earlier example
0x0000091d
julia> ncodeunits(jha)
3
julia> ncodeunits('a') # ASCII character
1
julia> ncodeunits('😱') # emoji
4
Ráadásul nem minden, a képernyőn megjeleníthető dolognak van saját egyedi kódpontja. Néhány vizuálisan elkülönülő karakter másokból származónak tekinthető, így a Unicode ezeket egy szülőkarakter és egy módosító kombinációjaként kezeli.
Ez a probléma a stringeket érinti, ahol kihívást jelent az indexelésnél.
Ebben a feladatban segédfüggvények egy részét valósítod meg, amelyek segítenek egy fejlesztőnek megtisztítani az azonosítók neveit.
A 6 részfeladatban fokozatosan építed fel a transform függvényt az egyes karakterek átalakításához, és a clean függvényt a stringek átalakításához.
Egy érvényes azonosító nulla vagy több betűből, aláhúzásjelből, kötőjelből, kérdőjelből és emojiből áll.
Ha üres stringet adsz át a clean függvénynek, akkor üres stringet kell visszaadnia.
Valósítsd meg a transform függvényt, hogy a kötőjeleket aláhúzásjelre cserélje.
julia> transform('-')
"_"
Távolítsd el az összes szóköz karaktert. Ez magában foglalja a kezdő és a záró szóközöket is.
julia> transform(' ')
""
Módosítsd a transform függvényt, hogy a camelCase-t kebab-case-re alakítsa.
julia> transform('D')
"-d"
Módosítsd a transform függvényt, hogy kihagyja a numerikus karaktereket.
julia> transform('7')
""
Módosítsd a transform függvényt, hogy az 'α' és 'ω' közötti görög betűket kérdőjelre cserélje.
julia> transform('β')
"?"
Valósítsd meg a clean függvényt, hogy ezeket a műveleteket egy teljes stringre alkalmazza.
A szabályokon kívül eső karakterek változatlanul menjenek át.
julia> clean(" a2b Cd-ω😀 ")
"ab-cd_?😀"
Iratkozz fel az Exercism-re, hogy megtanuld és elsajátítsd a(z) Julia nyelvet 35 fogalom128 feladat segítségével, valódi emberi mentorálással, mindez ingyen.