Kurzusok
/
Go
Go
/
Feladatok
/
Logfájlok elemzése
Logfájlok elemzése

Logfájlok elemzése

Tanulófeladat

Bevezetés

A regexp csomag támogatást nyújt a reguláris kifejezésekhez Go-ban.

Szintaxis

Az elfogadott reguláris kifejezések szintaxisa ugyanaz az általános szintaxis, amelyet a Perl, a Python és más nyelvek használnak.

A keresési minták és a bemeneti szövegek is UTF-8-ként értelmeződnek.

Amikor backtickeket használunk sztringek létrehozásához, a fordított perjelek () to make strings, backslashes () nem jelentenek semmit, és nem jelölik speciális karakterek, például tabulátor ) don't have any special meaning and don't mark the beginning of special characters like tabs vagy sortörés or newlines kezdetét:

"\t\n" // regular string literal with 2 characters: a tab and a newline
`\t\n`// raw string literal with 4 characters: two backslashes, a 't', and an 'n'

Emiatt a reguláris kifejezésekhez érdemes backtickeket használni, mert így nem kell escape-elni a fordított perjeleket:

"\\" // string with a single backslash
`\\` // string with 2 backslashes

Minták lefordítása - RegExp típus

Egy reguláris kifejezés használatához először le kell fordítanunk a sztringmintát. A lefordítás itt azt jelenti, hogy fogjuk a reguláris kifejezés sztringmintáját, és átalakítjuk egy belső reprezentációvá, amellyel könnyebb dolgozni. Minden mintát csak egyszer kell lefordítanunk, utána a reguláris kifejezés lefordított változatát sokszor használhatjuk. A regexp.Regexp típus egy lefordított reguláris kifejezést reprezentál. Egy sztringmintát a regexp.Compile függvénnyel fordíthatunk le regexp.Regexp típusúvá. Ez a függvény nil-t és egy hibát ad vissza, ha a lefordítás nem sikerült:

re, err := regexp.Compile(`(a|b)+`)
fmt.Println(re, err) // => (a|b)+ <nil>
re, err = regexp.Compile(`a|b)+`)
fmt.Println(re, err) // => <nil> error parsing regexp: unexpected ): `a|b)+`

A MustCompile függvény kényelmes alternatívája a Compile-nak:

re = regexp.MustCompile(`[a-z]+\d*`)

Ezzel a függvénnyel nem kell a hibát kezelni.

Caution

A MustCompile-t csak akkor használd, ha biztosan tudod, hogy a minta lefordul, különben a program pánikol.

A reguláris kifejezés metódusai

A Regexp típusnak 16 metódusa illeszt reguláris kifejezést és azonosítja az illeszkedő szöveget. A nevükre ez a reguláris kifejezés illeszkedik:

Find(All)?(String)?(Submatch)?(Index)?
  • Ha az All szerepel, a metódus a teljes kifejezés egymást követő, nem átfedő illeszkedéseit keresi.
  • Ha a String szerepel, az argumentum sztring; egyébként bájtok szelete; a visszatérési értékek ennek megfelelően módosulnak.
  • Ha a Submatch szerepel, a visszatérési érték egy szelet, amely a kifejezés egymást követő részilleszkedéseit azonosítja.
  • Ha az Index szerepel, az illeszkedéseket és részilleszkedéseket a bemeneti sztringen belüli bájtindexpárok azonosítják.

Vannak továbbá metódusok a következőkre:

  • reguláris kifejezések illeszkedéseinek helyettesítése cseresztringekkel, és
  • a reguláris kifejezésekkel elválasztott sztringek felosztása.

Összességében a regexp csomag több mint 40 függvényt és metódust definiál. Az alábbiakban néhány metódus használatát mutatjuk be. Ezeknek és más függvényeknek a részleteit lásd az API-dokumentációban.

MatchString példák

A MatchString metódus megmondja, hogy egy sztring tartalmaz-e illeszkedést egy reguláris kifejezésre.

re = regexp.MustCompile(`[a-z]+\d*`)
b = re.MatchString("[a12]")       // => true
b = re.MatchString("12abc34(ef)") // => true
b = re.MatchString(" abc!")       // => true
b = re.MatchString("123 456")     // => false

FindString példák

A FindString metódus egy sztringet ad vissza, amely a reguláris kifejezés legbaloldalibb illeszkedésének szövegét tartalmazza.

re = regexp.MustCompile(`[a-z]+\d*`)
s = re.FindString("[a12]")       // => "a12"
s = re.FindString("12abc34(ef)") // => "abc34"
s = re.FindString(" abc!")       // => "abc"
s = re.FindString("123 456")     // => ""

FindStringSubmatch példák

A FindStringSubmatch metódus sztringek egy szeletét adja vissza, amely a reguláris kifejezés legbaloldalibb illeszkedésének szövegét, valamint az alkifejezéseinek illeszkedéseit tartalmazza, ha vannak ilyenek. Ezzel azonosíthatók az elfogó csoportokra illeszkedő sztringek. A nil visszatérési érték azt jelenti, hogy nincs illeszkedés.

re = regexp.MustCompile(`[a-z]+(\d*)`)
sl = re.FindStringSubmatch("[a12]")       // => []string{"a12","12"}
sl = re.FindStringSubmatch("12abc34(ef)") // => []string{"abc34","34"}
sl = re.FindStringSubmatch(" abc!")       // => []string{"abc",""}
sl = re.FindStringSubmatch("123 456")     // => <nil>

ReplaceAllString példák

A re.ReplaceAllString(src,repl) metódus a src egy másolatát adja vissza, amelyben a re reguláris kifejezés illeszkedéseit a repl cseresztringre cseréli.

re = regexp.MustCompile(`[a-z]+\d*`)
s = re.ReplaceAllString("[a12]", "X")       // => "[X]"
s = re.ReplaceAllString("12abc34(ef)", "X") // => "12X(X)"
s = re.ReplaceAllString(" abc!", "X")       // => " X!"
s = re.ReplaceAllString("123 456", "X")     // => "123 456"

Split példák

A re.Split(s,n) metódus a s szöveget a kifejezéssel elválasztott részsztringekre bontja, és visszaadja a kifejezés illeszkedései közötti részsztringek szeletét. Az n szám határozza meg a visszaadandó részsztringek maximális számát. Ha n<0, a metódus az összes részsztringet visszaadja.

re = regexp.MustCompile(`[a-z]+\d*`)
sl = re.Split("[a12]", -1)      // => []string{"[","]"}
sl = re.Split("12abc34(ef)", 2) // => []string{"12","(ef)"}
sl = re.Split(" abc!", -1)      // => []string{" ","!"}
sl = re.Split("123 456", -1)    // => []string{"123 456"}

Utasítások

Ez a feladat a naplófájlok feldolgozásával foglalkozik.

Egy nemrég lezajlott biztonsági felülvizsgálat után arra kértek, hogy tisztítsd meg a szervezet archivált naplófájljait.

A függvényeknek átadott összes string garantáltan nem nullértékű, és nem tartalmaz sem vezető, sem záró szóközt.

1. Azonosítsd a hibás naplósorokat

Kell némi fogalmad arról, hogy az archívumodban hány naplósor nem felel meg a jelenlegi szabványoknak. Úgy gondolod, hogy egy egyszerű vizsgálat megmutatja, érvényes-e egy naplósor. Ahhoz, hogy egy sor érvényesnek számítson, a következő stringek egyikével kell kezdődnie:

  • [TRC]
  • [DBG]
  • [INF]
  • [WRN]
  • [ERR]
  • [FTL]

Valósítsd meg az IsValidLine függvényt, amely false-t ad vissza, ha egy string érvénytelen, egyébként pedig true-t.

IsValidLine("[ERR] A good error here")
// => true
IsValidLine("Any old [ERR] text")
// => false
IsValidLine("[BOB] Any old text")
// => false

2. Bontsd fel a naplósort

Egy új csapat csatlakozott a szervezethez, és azt tapasztalod, hogy a naplófájljaikban furcsa elválasztó választja el a „mezőket”. Ahelyett, hogy valami értelmeset, például kettőspontot (":") használnának, olyan stringet írnak, mint a "<--->" vagy a "<=>" (mert az szebb). Valójában bármilyen stringet, amelynek az első karaktere "<", az utolsó pedig ">", és közte a következő karakterek bármilyen kombinációja állhat: "~", "*", "=" és "-".

Valósítsd meg a SplitLogLine függvényt, amely egy sort kap, és olyan stringekből álló tömböt ad vissza, amelyek mindegyike egy mezőt tartalmaz.

SplitLogLine("section 1<*>section 2<~~~>section 3")
// => []string{"section 1", "section 2", "section 3"},

3. Számold meg, hány sor tartalmaz password szöveget idézőjelek között

A csapatnak tudnia kell az idézőjelek között szereplő jelszóhivatkozásokról, hogy azokat manuálisan megvizsgálhassák.

Valósítsd meg a CountQuotedPasswords függvényt, amely jelzi, mekkora lehet a manuális vizsgálat várható mértéke.

Azonosítsd azokat a naplósorokat, amelyekben a "password" stringet idézőjelek veszik körül, és amelyben a kis- és nagybetűk bármilyen kombinációban szerepelhetnek. Számolj azzal a lehetőséggel, hogy az idézőjelek között a "password" előtt és után további tartalom is lehet. Minden sor legfeljebb két idézőjelet tartalmaz.

A rutinnak átadott sorok érvényesek is lehetnek, meg nem is, az 1. részfeladatban meghatározottak szerint. Ugyanúgy dolgozzuk fel őket, akár érvényesek, akár nem.

lines := []string{
    `[INF] passWord`, // contains 'password' but not surrounded by quotation marks
    `"passWord"`,  // count this one
    `[INF] User saw error message "Unexpected Error" on page load.`, // does not contain 'password'
    `[INF] The message "Please reset your password" was ignored by the user`, // count this one
}
// => 2

4. Távolítsd el a napló maradványait

Rájöttél, hogy a naplók valamelyik feldolgozási lépése szétszórta a naplókban az "end-of-line" szöveget, amelyet egy sorszám követ (közöttük szóköz nélkül).

Valósítsd meg a RemoveEndOfLineText függvényt, amely átvesz egy stringet, eltávolítja belőle az end-of-line szöveget, és egy „tiszta” stringet ad vissza.

Az end-of-line szöveget nem tartalmazó sorokat változatlanul kell visszaadni.

Csak az end-of-line stringet távolítsd el. Ne próbáld módosítani a szóközöket.

RemoveEndOfLineText("[INF] end-of-line23033 Network Failure end-of-line27")
// => "[INF]  Network Failure "

5. Címkézd meg a sorokat felhasználónevekkel

Észrevetted, hogy néhány naplósor olyan mondatot tartalmaz, amely felhasználókra utal. Ezek a mondatok mindig tartalmazzák a "User" stringet, amelyet egy vagy több szóköz, majd egy felhasználónév követ. Úgy döntesz, hogy megcímkézed ezeket a sorokat.

Valósítsd meg a TagWithUserName függvényt, amely feldolgozza a naplósorokat:

  • Azok a sorok, amelyek nem tartalmazzák a "User " stringet, változatlanok maradnak.
  • Azoknál a soroknál, amelyek tartalmazzák a "User " stringet, a sor elé írd a [USR] előtagot, majd a felhasználónevet.

Például:

result := TagWithUserName([]string{
    "[WRN] User James123 has exceeded storage space.",
	"[WRN] Host down. User   Michelle4 lost connection.",
	"[INF] Users can login again after 23:00.",
	"[DBG] We need to check that user names are at least 6 chars long.",
})
// => []string {
//  "[USR] James123 [WRN] User James123 has exceeded storage space.",
//  "[USR] Michelle4 [WRN] Host down. User   Michelle4 lost connection.",
//  "[INF] Users can login again after 23:00.",
//  "[DBG] We need to check that user names are at least 6 chars long."
// }

Feltételezheted, hogy:

  • A felhasználóneveket a naplóban legalább egy whitespace-karakter követi.
  • Minden sorban legfeljebb egyszer fordul elő a "User " string.
  • A felhasználónevek nem üres stringek, amelyek nem tartalmaznak whitespace-t.
Szerkesztés GitHubon A hivatkozás új ablakban vagy lapon nyílik meg
Go Exercism

Készen állsz elkezdeni a(z) Logfájlok elemzése feladatot?

Iratkozz fel az Exercism-re, hogy megtanuld és elsajátítsd a(z) Go nyelvet 34 fogalom165 feladat segítségével, valódi emberi mentorálással, mindez ingyen.