Logszintek

Logszintek

Tanulófeladat

Bevezetés

A String a Julia nyelvben karakterek rendezett sorozata. Ahogy a kézikönyv rámutat: „Természetesen az igazi baj akkor kezdődik, amikor valaki felteszi a kérdést, mi is az a karakter.”

Ennek a bonyolultságnak a nagy részét részletesebben a Chars fogalom tárgyalja, de röviden:

  • A Julia nyelvben minden string Unicode.
  • Azok a stringek, amelyek egyben ASCII-k is (az angol ábécé nagy- és kisbetűi A-tól Z-ig, számjegyek és néhány írásjel), könnyen kezelhetők.
  • A világ legtöbb más írásrendszerével lehet dolgozni, de több odafigyelést igényel.

String literálok

Általában a stringeket kettős idézőjelek " " közé zárjuk. Az egyszeres idézőjeleket ' ' csak Chars esetén használjuk.

Hármas kettős idézőjelek """ """ is használhatók, amelyek lehetővé teszik, hogy a stringen belül " szerepeljen escape-elés nélkül. Ami még fontosabb: a többsoros stringekről eltávolítja a nem kívánt extra behúzást.

julia> """
       Multiline
       
       """
"Multiline\nString\n"

Karakterek escape-elése

A C-től kezdődő nyelvek többségéhez hasonlóan a Julia is backslash \ karaktert használ escape-elésre:

  1. Nem nyomtatható karakterek beírásához, például az előző példában szereplő új sor \n jeléhez.
  2. Olyan karakterek védelmére, amelyek egyébként különleges jelentéssel bírnának, például a \$ (lásd lentebb).

Indexelés

Elvileg a stringek pontosan úgy indexelhetők, mint a vektorok:

julia> s[1], s[5]
('J', 'a')

Ez nyilvánvalóan működik egy olyan ASCII stringnél, mint a „Julia”, de ezzel a világ nyelveinek nagy részét figyelmen kívül hagyjuk.

Vegyük például a Beowulf egyik karakterét, amelyet körülbelül 15 évszázaddal ezelőtt óangolul írtak.

A „Hrōðgār” egyértelműen 7 karakterből áll, de nem mindegyik ASCII.

julia> king = "Hrōðgār"
"Hrōðgār"

julia> length(king)
7

julia> isascii(king)
false

# collect() converts to a Char vector:
julia> collect(king)
7-element Vector{Char}:
 'H': ASCII/Unicode U+0048 (category Lu: Letter, uppercase)
 'r': ASCII/Unicode U+0072 (category Ll: Letter, lowercase)
 'ō': Unicode U+014D (category Ll: Letter, lowercase)
 'ð': Unicode U+00F0 (category Ll: Letter, lowercase)
 'g': ASCII/Unicode U+0067 (category Ll: Letter, lowercase)
 'ā': Unicode U+0101 (category Ll: Letter, lowercase)
 'r': ASCII/Unicode U+0072 (category Ll: Letter, lowercase)

Egy ilyen string indexelése jól indul, de egy ponton elromlik:

julia> king[3]
'ō': Unicode U+014D (category Ll: Letter, lowercase)

julia> king[4]
ERROR: StringIndexError: invalid index [4], valid nearby indices [3]=>'ō', [5]=>'ð'

A probléma az, hogy az ilyen indexelés bájtokat számol, amelyek a nem ASCII stringeknél nincsenek 1:1 kapcsolatban a karakterekkel. Egy Unicode/UTF-8 karakter ábrázolásához akár 4 bájt is kellhet, és a Chars fogalom ezt részletesebben is tárgyalja.

Stringek építése

Összefűzés

Sok nyelv a + operátort használja stringek összefűzésére, a Julia azonban nem. Legalább a hibaüzenet hasznos.

julia> "s1 " + "s2"
ERROR: MethodError: no method matching +(::String, ::String)
The function `+` exists, but no method is defined for this combination of argument types.
String concatenation is performed with * 

julia> "s1 " * "s2"
"s1 s2"

A string() függvény tetszőleges számú stringet fűz össze.

julia> string("lots ", "of ", "bits")
"lots of bits"

A join() függvény ugyanezt teszi, és egy stringekből álló vektort is képes megadott elválasztóval összefűzni (alapértelmezésben "").

julia> join(["lots", "of", "bits"], "_")
"lots_of_bits"

Ne feledjük, hogy a stringek megváltoztathatatlanok, az összefűzés pedig másolással jár. Ezért a cikluson belüli ismételt összefűzés nem hatékony, jobb, ha a darabokat egy vektorban gyűjtjük össze, és a végén fűzzük össze az összeset.

Ismétlés

Egyszerű:

julia> repeat("Abc", 5)
"AbcAbcAbcAbcAbc"

Interpoláció

Sok nyelvben van mód számított értékek stringbe illesztésére, bár abban meglepően nagy az egyet nem értés, hogy melyik a legjobb szintaxis.

A Juliában az interpolált értékeket $ előzi meg.

julia> myvar = 42
42

julia> "myvar evaluates to $myvar"
"myvar evaluates to 42"

julia> r = 5.3
5.3

julia> "A circle of radius $r has area $(π * r^2)"
"A circle of radius 5.3 has area 88.24733763933729"

Zárójelekre akkor van szükség, ha elhagyásuk kétértelmű lenne, de egyetlen, szóközzel követett azonosító esetén elhagyhatók.

Ha egy $ jelet szeretnél a stringbe írni, escape-eld \$ alakban.

Vegyük figyelembe a korlátot: az interpoláció jelenleg nem tesz lehetővé formázást, például a megjelenítendő tizedesjegyek számának beállítását.

@sprintf()

A stringek összeállítása feletti finomabb vezérléshez a Julia átveszi a C-ből a sprintf függvényt (és számos későbbi nyelvből is: a Wikipédia körülbelül 30-at sorol fel).

A Juliában ezt a Printf modulon belüli macro valósítja meg, innen az @ előtag.

julia> using Printf

julia> r = 5.3
5.3

julia> @sprintf("A circle of radius %.1f has area %.2f", r, π * r^2)
"A circle of radius 5.3 has area 88.25"

Stringfüggvények

Az egyszerűség kedvéért ez a szakasz azokra a függvényekre összpontosít, amelyek új stringet adnak vissza, és a bemenetet változatlanul hagyják. Soknak van ! utótaggal jelölt megfelelője, amely helyben módosítja a bemenetet.

Hossz

Milyen hosszú egy string? Néha attól függ, hogyan számolsz.

Az egyszerű eset az ASCII stringek, ahol minden karakter 1 bájtot foglal el.

julia> string_asc = "Julia"
"Julia"

julia> length(string_asc)
5

julia> sizeof(string_asc)
5

A length() függvény a karakterek számát adja vissza, a sizeof() pedig a bájtok számát.

Ez a különbség más karakterkészleteknél válik fontossá:

julia> king = "Hrōðgār"
"Hrōðgār"

julia> length(king)
7

julia> sizeof(king)
10

Felosztás

A programozásban gyakori művelet egy hosszú stringet darabokra bontani egy vagy több karakterből álló elválasztó string alapján.

Általában a split() függvényt használjuk. Az elválasztó alapértelmezésben bármilyen whitespace, de más is megadható.

julia> split("my little string")
3-element Vector{SubString{String}}:
 "my"
 "little"
 "string"

julia> split("My_snake_case_string", "_")
4-element Vector{SubString{String}}:
 "My"
 "snake"
 "case"
 "string"

Ezek a példák egy stringet kisebb stringekre bontanak. Egy string karakterekre bontása más művelet.

Keresés és csere

Tartalmaz egy string egy megadott részstringet? Furcsamód két függvény is teszteli ezt: az occursin() és a contains() csak az argumentumaik sorrendjében térnek el.

julia> needle = "Julia"
"Julia"

julia> haystack = "Python, Julia and R"
"Python, Julia and R"

julia> occursin(needle, haystack)
true

julia> contains(haystack, needle)
true

Ha pontosabban szeretnénk meghatározni a pozíciót:

julia> startswith(haystack, "Python")
true

julia> endswith(haystack, "Python")
false

Egy részstring kezdő és záró indexének meghatározásához több függvényünk is van:

  • findfirst()
  • findlast()
  • findprev()
  • findnext()
julia> findfirst(needle, haystack)
9:13

Részstringek cseréjéhez soroljuk fel a változtatásokat x => y szintaxissal.

julia> replace("abc", "a"=>"b", "b"=>"c", "c"=>"a")
"bca"

A Julia 1.7 óta a replace függvény tetszőleges számú változtatást fogadhat, azzal a garanciával, hogy a csere során egyetlen karakter sem változik meg egynél többször.

Az x => y szintaxist pair-nek nevezik, ami egy fontos típus a Juliában, és amelyről részletesebben a Dicts and Pairs fogalomban lesz szó.

Whitespace

Gyakran kell eltávolítanunk egy string elejéről és/vagy végéről a whitespace-t.

Erre szolgálnak az lstrip() (bal), rstrip() (jobb) és strip() (mindkettő) függvények.

julia> strip("\n\t  useful_bit\n\n")
"useful_bit"

Betűváltás

Ezeknek a függvényeknek meglehetősen beszédes neveik vannak:

julia> s = repeat("aBcD ", 5)
"aBcD aBcD aBcD aBcD aBcD "

julia> uppercase(s)
"ABCD ABCD ABCD ABCD ABCD "

julia> lowercase(s)
"abcd abcd abcd abcd abcd "

julia> titlecase(s)  # Initial letter of each word uppercase
"Abcd Abcd Abcd Abcd Abcd "

Utasítások

Ebben a feladatban naplósorokat dolgozol fel.

Minden naplósor egy karakterlánc, amelynek formátuma a következő: "[<LEVEL>]: <MESSAGE>".

Három különböző naplózási szint van:

  • INFO
  • WARNING
  • ERROR

Három részfeladat vár rád, és mindegyik kap egy naplósort, amelyikkel valamit tenned kell.

1. Üzenet kinyerése egy naplósorból

Valósítsd meg a message függvényt, amely visszaadja a naplósor üzenetét:

julia> message("[ERROR]: Invalid operation")
"Invalid operation"

A vezető és a záró szóközt el kell távolítani:

julia> message("[WARNING]:  Disk almost full\r\n")
"Disk almost full"

2. Naplózási szint kinyerése egy naplósorból

Valósítsd meg a log_level függvényt, amely visszaadja a naplósor naplózási szintjét, méghozzá kisbetűvel:

julia> log_level("[ERROR]: Invalid operation")
"error"

3. Naplósor újraformázása

Valósítsd meg a reformat függvényt, amely újraformázza a naplósort: az üzenetet előre teszi, a naplózási szintet pedig utána, zárójelben:

julia> reformat("[INFO]: Operation completed")
"Operation completed (info)"

Megjegyzés: Ebben a feladatban minden karakterlánc angol nyelvű, és az ASCII-karakterkészletre korlátozódik. A későbbi fogalmak során lehetőséged nyílik majd Unicode-karakterekkel dolgozni.

Szerkesztés GitHubon A hivatkozás új ablakban vagy lapon nyílik meg
Julia Exercism

Készen állsz elkezdeni a(z) Logszintek feladatot?

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.