Programování v C# Soubory a regulární výrazy Petr Vaněček 1 / 27
Obsah přednášky Informace o prostředí Práce se soubory Regulární výrazy 2 / 27
Zprostředkování informací Třída System.Environment Poskytuje info o systému, procesu, uživateli,... 3 / 27
Systém a verze OSVersion informace o platformě a verzi Version verze runtimu UserName uživatelské jméno vlastníka procesu UserDomainName název domény MachineName název počítače 4 / 27
Cesty CurrentDirectory aktuální adresář SystemDirectory systémový adresář (většino c:/windows/system32) GetFolderPath(SpecialFolder) cesty ke speciálním adresářům ApplicationData data aplikací Desktop plocha MyMusic hudba StartMenu nabídka start... GetCommandLineArgs parametry příkazové řádky včetně jména souboru 5 / 27
Proudy V.NET všechny I/O operace řešeny pomocí proudů Třída System.IO.Stream abstraktní pohled na množinu bytů soubor paměť TCP/IP... společné metody Read Write u některých proudu navíc náhodný přístup metoda Seek vlastnost Position 6 / 27
Třída FileStream Pro práci se soubory Otevření souboru probíhá v konstruktoru FileStream soubor = new FileStream(string, FileMode); FileMode určuje způsob otevření Create vytvoří či přepíše soubor Append otevře existující soubor a zapisuje na jeho konec nebo vytvoří nový soubor Open otevře existující soubor Při zápisu se využívá buffer nutno korektně uzavřít soubor Close 7 / 27
Příklad použití třídyfilestream FileStream fs = null ; try { fs = new FileStream (" prvni ",FileMode. Create ); byte [] s = new byte []{( byte ) p }; fs. Write (s,0,1); } finally { fs. Close (); } nebo using (fs = new FileStream (" prvni ",FileMode. Create )) { byte [] s = new byte []{( byte ) p }; fs. Write (s,0,1); } 8 / 27
Třídy BinaryWriter/Reader Práce s binárními daty Konstruktory BinaryReader/Writer(Stream, Encoding) možnost nastavit použité kódování Implementují metody pro práci se základními typy... Read...() načte z proudu hodnotu byte ReadByte() void Write() zapíše do proudu data 9 / 27
Třídy TextReader/Writer Práce s textem Odděděné třídy StringReader/Writer čtení/zápis do řetězce StreamReader/Writer čtení/zápis do proudu Konstruktory StreamReader/Writer(string/Stream, Encoding) Metody Read/WriteLine 10 / 27
Příklad použití tříd StreamReader/Writer using ( StreamWriter soubor = new StreamWriter (" pokus ", false, Encoding. UTF8 )) { soubor. WriteLine (" můžeme psát česky "); } using ( StreamReader soubor = new StreamReader (" pokus ", Encoding. UTF8 )) { string retezec = soubor. ReadLine (); Console. WriteLine ( retezec ); } 11 / 27
Třídy File a FileInfo Obsahují metody pro práci se soubory otevírání, kopírování, mazání,... Třída File obsahuje statické metody Třída FileInfo obsahuje instanční metody vyplatí se při více operacích nad jedním souborem nedochází k opakované kontrole práv Diskové operace metoda MoveTo přesun souboru metoda CopyTo kopírování metoda Delete mazání Zjišťování a nastavování přístupu vlastnost LastAccessTime poslední přístup vlastnost Attributes atributy 12 / 27
Třídy File a FileInfo v.net 2 Zjednodušení práce se soubory Načtení a zápis celého souboru pomocí jedné metody string ReadAllText string[] ReadAllLines WriteAllText(string) WrtieAllLines(string[]) 13 / 27
Třídy Directory a DirectoryInfo Dvě verze podobně jako u souborů Umožňují operace s adresáři Delete Move Zjištění obsahu adresáře GetDirectories GetFiles Zjišťování a nastavování přístupu Změna aktuálního adresáře SetCurrentDirectory 14 / 27
Práce s cestami Třída Path Pracuje pouze s řetězcem Umožňuje získávat a měnit části cesty GetExtension vrátí příponu ChangeExtension vrátí cestu se změněnou příponou HasExtension rozhodne zda cesta obsahuje i příponu GetFileName jméno souboru GetDirectoryName jméno adresáře... 15 / 27
Příklad string soubor = Environment. GetCommandLineArgs ()[0]; soubor = Path. ChangeExtension ( soubor,".cs"); if( File. Exists ( soubor )) { string [] radky = File. ReadAllLines ( soubor ); foreach ( string radka in radky ) { Console. WriteLine ( radka ); } } 16 / 27
Hlídání souborů Třída FileSystemWatcher sleduje změny v nastaveném adresáři Vyvolává události Changed změna Created vytvoření Deleted smazání Renamed přejmenování Pomocí vlastností Filter a NotifyFilter možno nastavit jaké události a které soubory se mají sledovat 17 / 27
Hlídání souborů příklad public static void Main ( string [] Args ) { string cesta = Environment. GetCommandLineArgs ()[0]; cesta = Path. GetDirectoryName ( cesta ); FileSystemWatcher hlidac = new FileSystemWatcher ( cesta ); hlidac. Created += new FileSystemEventHandler ( Vytvoreni ); hlidac. EnableRaisingEvents = true ; } Console. WriteLine (" Tady hlidam ja"); Console. ReadKey (); private static void Vytvoreni ( object source, FileSystemEventArgs e) { Console. WriteLine (" Vytvoril se: " + e. FullPath ); } 18 / 27
Co jsou vlastně zač? Co jsou regulární výrazy? 19 / 27
Co jsou vlastně zač? Co jsou regulární výrazy? univerzální pomocník při práci s textem vyhledávání rozdělování nahrazování 19 / 27
Co jsou vlastně zač? Co jsou regulární výrazy? univerzální pomocník při práci s textem vyhledávání rozdělování nahrazování Jak to vypadá? 19 / 27
Co jsou vlastně zač? Co jsou regulární výrazy? univerzální pomocník při práci s textem vyhledávání rozdělování nahrazování Jak to vypadá? kombinace normálních a řídících znaků, které definují vzor (pattern) 19 / 27
Co jsou vlastně zač? Co jsou regulární výrazy? univerzální pomocník při práci s textem vyhledávání rozdělování nahrazování Jak to vypadá? kombinace normálních a řídících znaků, které definují vzor (pattern) A v praxi? 19 / 27
Co jsou vlastně zač? Co jsou regulární výrazy? univerzální pomocník při práci s textem vyhledávání rozdělování nahrazování Jak to vypadá? kombinace normálních a řídících znaků, které definují vzor (pattern) A v praxi? např. e vyhledá písmeno e eva vyhledá řetězec eva 19 / 27
Více znaků Libovolný znak 20 / 27
Více znaků Libovolný znak e.a eva, ema, esa,... 20 / 27
Více znaků Libovolný znak e.a eva, ema, esa,... Množina znaků 20 / 27
Více znaků Libovolný znak e.a eva, ema, esa,... Množina znaků e[vm]a eva,ema e[^m]a eva, esa, eta, (ne ema) 20 / 27
Více znaků Libovolný znak e.a eva, ema, esa,... Množina znaků e[vm]a eva,ema e[^m]a eva, esa, eta, (ne ema) Speciální znaky 20 / 27
Více znaků Libovolný znak e.a eva, ema, esa,... Množina znaků e[vm]a eva,ema e[^m]a eva, esa, eta, (ne ema) Speciální znaky \w alfanumerický znak \d číslo \s bílý znak (mezera, tabulátor,... ) 20 / 27
Více znaků Libovolný znak e.a eva, ema, esa,... Množina znaků e[vm]a eva,ema e[^m]a eva, esa, eta, (ne ema) Speciální znaky \w alfanumerický znak \d číslo \s bílý znak (mezera, tabulátor,... ) A tečka? 20 / 27
Více znaků Libovolný znak e.a eva, ema, esa,... Množina znaků e[vm]a eva,ema e[^m]a eva, esa, eta, (ne ema) Speciální znaky \w alfanumerický znak \d číslo \s bílý znak (mezera, tabulátor,... ) A tečka? \. 20 / 27
Skupiny (vzor) se skupinami možno dále pracovat Jednotlivé skupiny jsou číslovány (celý výraz má číslo 0) \číslo zopakování skupiny ve výrazu (.)\1 21 / 27
Skupiny (vzor) se skupinami možno dále pracovat Jednotlivé skupiny jsou číslovány (celý výraz má číslo 0) \číslo zopakování skupiny ve výrazu (.)\1 dva po sobě jdoucí shodné znaky 21 / 27
Skupiny (vzor) se skupinami možno dále pracovat Jednotlivé skupiny jsou číslovány (celý výraz má číslo 0) \číslo zopakování skupiny ve výrazu (.)\1 dva po sobě jdoucí shodné znaky $číslo použití skupiny při nahrazování Replace "(.)(.)", "$2$1" 21 / 27
Skupiny (vzor) se skupinami možno dále pracovat Jednotlivé skupiny jsou číslovány (celý výraz má číslo 0) \číslo zopakování skupiny ve výrazu (.)\1 dva po sobě jdoucí shodné znaky $číslo použití skupiny při nahrazování Replace "(.)(.)", "$2$1" prohození pořadí každých dvou znaků 21 / 27
Skupiny (vzor) se skupinami možno dále pracovat Jednotlivé skupiny jsou číslovány (celý výraz má číslo 0) \číslo zopakování skupiny ve výrazu (.)\1 dva po sobě jdoucí shodné znaky $číslo použití skupiny při nahrazování Replace "(.)(.)", "$2$1" prohození pořadí každých dvou znaků Skupiny je možné pojmenovat (?<jmeno>vzor) pojmenování \<jmeno> definice vzoru ${jmeno} nahrazování 21 / 27
Další možnosti vyhledávání vzor1 vzor2 spojka nebo (em iv)a ema nebo iva ^ začátek řetězce $ konec řetězce \b začátek/konec slova \e[^\s]* celé slovo (ukončené mezerou) 22 / 27
Opakování * opakování vzoru (0-n) + opakování vzoru (minimálně jednou)? výskyt vzoru 0 nebo 1 krát {počet} pevný počet opakování {min,max} pevný počet opakování (rozmezí) Příklad: mama ma maso (ma)* - mama ma maso m.*m - mama ma maso ma\s*ma - mama ma maso ma\s+ma - mama ma maso (ma.?){3} - mama ma maso 23 / 27
Regulární výrazy v.netu Namespace System.Text.RegularExpression Třída Regex obsahuje statické i nestatické metody Match vyhledá vzor a vrátí první výskyt Matches vyhledá vzor a vrátí všechny výskyty IsMatch zjistí zda se vzor v řetězci nachází Split podle vzoru rozdělí řetězec na pole řetězců Replace vyhledá vzory a nahradí je řetězcem Pokud nejsou nutné regulární výrazy, použít metody třídy String IndexOf vyhledání Split rozdělení Replace nahrazení 24 / 27
Možnosti nahrazování Metoda Replace existuje v několika exemplářích možnost definovat vlastní metodu, která bude provádět složitější operace static string NaKila ( Match m) { string cislo = m. Groups [1]. ToString (); int velikost = int. Parse ( cislo ); velikost /= 1024; return velikost. ToString ()+ "kb"; }... string vysledek = Regex. Replace (text, @"(\d+)b", new MatchEvaluator ( NaKila )); 25 / 27
Pár příkladů na závěr Rodné číslo ( 000000/000? ) 26 / 27
Pár příkladů na závěr Rodné číslo ( 000000/000? ) \d{6}/\d{3,4} 26 / 27
Pár příkladů na závěr Rodné číslo ( 000000/000? ) \d{6}/\d{3,4} IP adresa ( 0??.0??.0??.0?? ) 26 / 27
Pár příkladů na závěr Rodné číslo ( 000000/000? ) \d{6}/\d{3,4} IP adresa ( 0??.0??.0??.0?? ) \d{1,3}(\.\d{1,3}){3} 26 / 27
Pár příkladů na závěr Rodné číslo ( 000000/000? ) \d{6}/\d{3,4} IP adresa ( 0??.0??.0??.0?? ) \d{1,3}(\.\d{1,3}){3} PSČ 26 / 27
Pár příkladů na závěr Rodné číslo ( 000000/000? ) \d{6}/\d{3,4} IP adresa ( 0??.0??.0??.0?? ) \d{1,3}(\.\d{1,3}){3} PSČ \d{3}?\d{2} 26 / 27
Pár příkladů na závěr Rodné číslo ( 000000/000? ) \d{6}/\d{3,4} IP adresa ( 0??.0??.0??.0?? ) \d{1,3}(\.\d{1,3}){3} PSČ \d{3}?\d{2} email ( x.x@x.x.x ) 26 / 27
Pár příkladů na závěr Rodné číslo ( 000000/000? ) \d{6}/\d{3,4} IP adresa ( 0??.0??.0??.0?? ) \d{1,3}(\.\d{1,3}){3} PSČ \d{3}?\d{2} email ( x.x@x.x.x ) [\w. -]+@[\w.-]+\.[a-za-z]{2,4} 26 / 27
Pár příkladů na závěr Rodné číslo ( 000000/000? ) \d{6}/\d{3,4} IP adresa ( 0??.0??.0??.0?? ) \d{1,3}(\.\d{1,3}){3} PSČ \d{3}?\d{2} email ( x.x@x.x.x ) [\w. -]+@[\w.-]+\.[a-za-z]{2,4} není 100% korektní vyhledávání vs. testování 26 / 27
Konec 27 / 27