A reguláris kifejezések (regex) hatékony eszközt jelentenek, ha Elixirben stringekkel dolgozunk. Az Elixirben a reguláris kifejezések a PCRE specifikációt követik (Perl Compatible Regular Expressions). A reguláris kifejezés jelentését leíró string-mintákat először lefordítjuk, majd a string egészének vagy egy részének illesztésére használjuk.
Az Elixirben a reguláris kifejezések létrehozásának leggyakoribb módja a ~r sigil használata. A sigilek szintaktikai cukor rövidítéseket kínálnak az Elixirben gyakori feladatokhoz. Egy string literál illesztéséhez magát a stringet használhatjuk mintaként a sigil után.
~r/test/
A =~/2 operátorral reguláris kifejezést illeszthetsz egy stringre, és boolean eredményt kapsz.
"this is a test" =~ ~r/test/
# => true
Két megjegyzés a sigilek használatához:
/ helyett\)A karakterek egy tartományának szögletes zárójellel ([]) való illesztése egy karakterosztályt definiál. Ez az osztályban szereplő karakterek bármelyikére illeszkedik. Megadhatsz karaktertartományt is, például a-z, feltéve hogy a kezdő és a záró karakter összefüggő kódponttartományt jelöl.
regex = ~r/[a-z][ADKZ][0-9][!?]/
"jZ5!" =~ regex
# => true
"jB5?" =~ regex
# => false
A rövidített karakterosztályok tömörebbé teszik a mintát. Például:
\d a [0-9] rövidítése (bármely számjegy)\w az [A-Za-z0-9_] rövidítése (bármely „szó” karakter)\s a [ \t\r\n\f] rövidítése (bármely whitespace karakter)Ha egy rövidített karakterosztályt sigilen kívül használsz, escape-elni kell: "\\d"
Az alternációknál a | speciális karakter jelzi, hogy az egyik vagy a másik lehetőségre illeszkedünk
regex = ~r/cat|bat/
"bat" =~ regex
# => true
"cat" =~ regex
# => true
A kvantifikátorok ismétlődő mintát tesznek lehetővé a reguláris kifejezésben. A kvantifikátort megelőző csoportra hatnak.
{N, M}, ahol N az ismétlődések minimális, M pedig a maximális száma{N,} legalább N ismétlődésre illeszkedik
{0,} felírható *-ként is: nulla vagy több ismétlődésre illeszkedik{1,} felírható +-ként is: egy vagy több ismétlődésre illeszkedik{,N} legfeljebb N ismétlődésre illeszkedikA kerek zárójelek (()) a csoportok és az elfogások jelölésére szolgálnak. A csoportot az esetek egy részében el is foghatjuk, hogy használatra visszakapjuk. Az Elixirben ezek lehetnek nevesítettek vagy névtelenek. Az elfogásokat úgy nevezzük el, hogy a nyitó zárójel után ?<name>-et írunk. A csoportok egyetlen egységként működnek, például amikor kvantifikátorok követik őket.
regex = ~r/(h)at/
Regex.replace(regex, "hat", "\\1op")
# => "hop"
regex = ~r/(?<letter_b>b)/
Regex.scan(regex, "blueberry", capture: :all_names)
# => [["b"], ["b"]]
A horgonyok ahhoz kellenek, hogy a reguláris kifejezést az illesztendő string elejéhez vagy végéhez kössük:
^ a string elejéhez horgonyoz$ a string végéhez horgonyozMivel a ~r a "pattern" |> Regex.escape() |> Regex.compile!() rövidítése, string-interpolációval dinamikusan is felépíthetsz egy reguláris kifejezés mintát:
anchor = "$"
regex = ~r/end of the line#{anchor}/
"end of the line?" =~ regex
# => false
"end of the line" =~ regex
# => true
Az a feladatod, hogy írj egy szolgáltatást, amely eseményeket dolgoz fel. Minden eseményhez tartozik egy dátum, de észreveszed, hogy három különböző formátumban küldik be őket a szolgáltatásod végpontjára:
"01/01/1970""January 1, 1970""Thursday, January 1, 1970"Látod, hogy van némi hasonlóság köztük, ezért úgy döntesz, hogy írsz néhány összeépíthető reguláris kifejezésmintát.
Valósítsd meg a day/0, month/0 és year/0 függvényt úgy, hogy egy olyan string-mintát adjanak vissza, amely lefordítva a "01/01/1970" (dd/mm/yyyy) numerikus részeire illeszkedik. A nap és a hónap 1 vagy 01 formában is szerepelhet (nullákkal balra kiegészítve).
"31" =~ DateParser.day() |> Regex.compile!()
# => true
"12" =~ DateParser.month() |> Regex.compile!()
# => true
"1970" =~ DateParser.year() |> Regex.compile!()
# => true
Valósítsd meg a day_names/0 és month_names/0 függvényt úgy, hogy egy-egy olyan string-mintát adjanak vissza, amely lefordítva rendre a hét megnevezett napjára, illetve az év megnevezett hónapjára illeszkedik.
"Tuesday" =~ DateParser.day_names() |> Regex.compile!()
# => true
"June" =~ DateParser.month_names() |> Regex.compile!()
# => true
Valósítsd meg a capture_day/0, capture_month/0, capture_year/0, capture_day_name/0 és capture_month_name/0 függvényt úgy, hogy egy olyan string-mintát adjanak vissza, amely a megfelelő részeket a következő nevek alá rögzíti: "day", "month", "year", "day_name", "month_name"
DateParser.capture_month_name()
|> Regex.compile!()
|> Regex.named_captures("December")
# => %{"month_name" => "December"}
Valósítsd meg a capture_numeric_date/0, capture_month_name_date() és capture_day_month_name_date/0 függvényt úgy, hogy egy olyan string-mintát adjanak vissza, amely a 3. részben szereplő részeket a megfelelő dátumformátum szerint rögzíti:
"01/01/1970"
"January 1, 1970"
"Thursday, January 1, 1970"
DateParser.capture_numeric_date()
|> Regex.compile!()
|> Regex.named_captures("01/01/1970")
# => %{"day" => "01", "month" => "01", "year" => "1970"}
Valósítsd meg a match_numeric_date/0, match_month_name_date/0 és match_day_month_name_date/0 függvényt úgy, hogy egy olyan lefordított reguláris kifejezést adjanak vissza, amely csak a dátumra illeszkedik, és a részeket is rögzíteni tudja.
"Thursday, January 1, 1970 was the Unix epoch." =~ DateParser.match_day_month_name_date()
# => false
"Thursday, January 1, 1970" =~ DateParser.match_day_month_name_date()
# => true
DateParser.match_day_month_name_date()
|> Regex.named_captures("Thursday, January 1, 1970")
# => %{
# "day" => "1",
# "day_name" => "Thursday",
# "month_name" => "January",
# "year" => "1970"
# }
Iratkozz fel az Exercism-re, hogy megtanuld és elsajátítsd a(z) Elixir nyelvet 58 fogalom168 feladat segítségével, valódi emberi mentorálással, mindez ingyen.