Die Skriptsprache Perl (3) Wolfgang Friebel DESY Zeuthen
Anmerkungen zu Teil 2 n Wahrheitswerte: 0, 0, 0,,, () und undef sind falsch n Wortzählung: while ( <> ) { chomp; for ( split ) { # split(/\s+/, $_) $anzahl{$_}++; # Interpunktion entfernen? } }# danach Ausgabe von %anzahl Einzeiler mit -p und -n (unter NT) (LF->CR/LF, grep) perl -pe s/\012/\n/ unix.txt > dos.txt perl -ne print if /Suchtext/ Datei
4. Reguläre Ausdrücke n zum Suchen und Ersetzen von Strings n werden auch in anderen Programmen benutzt awk, sed, vi, egrep (Untermenge von perl-regex) Suchen mit dem Match-Operator m/regex/ Klammern wie bei q, qw,.. (d.h. auch m(), m[], m!! ) Bei / als Begrenzer kann m entfallen ( /regex/ ) Ersetzen mit Substitute-Operator s/regex/string/ n Optionen modifizieren Operatorverhalten z.B. m/regex/i und s/regex/string/g
Suchen und Ersetzen ohne Regex n Suchen mit index: (index string, substring, offset) $found = 1 if index ($_, string) >= 0; n Ersetzen mit substr: (substr string, offset, length) $was = Hahn; substr($was, 0, 1) = W; substr($was, -1, 1) = r; n Funktion substr kann links und rechts von = stehen n substr und index sind meist schneller als Regex, eventuell ist die Lesbarkeit von Regex besser (perl5.005 optimiert konstante Strings -> index)
Suchen in Tabellen n kann ohne Regex vorteilhafter sein u bei fester Zuordnung Spalten/Inhalt u keine Probleme, wenn Spalten zusammenfließen = unpack muster, string string wird nach Anweisung in Muster zerhackt Muster z.B.: A10xA5 (10 Char, 1 ignoriertes, 5Char) Verwendung anderer Typen, dann keine fixe Spalten Siehe manpage (perlfunc)
Worin wird gesucht n Bei m// und s/// wird in $_ gesucht/ersetzt n Verhalten durch Pattern binding Operator änderbar $ok = 1 if $a =~ /string/; #Suche in $a $notok = 1 if $b !~ /string/; #Suche in $b $ok = 1 if $c =~ s/hü/hott/;#Ersetze in $c n Resultat ist bei Erfolg wahr für =~, falsch für !~ n Listkontext: gefundene/ersetzte Strings als Resultat ($program = $0) =~ s(^.*/)(); #Scriptname
Elemente regulärer Ausdrücke n Alle ASCII Zeichen (Zeichen \|()[{^$*+?. nur mit \) n Metazeichen (Zeichen \|()[{^$*+?. und andere mit \) n Klassen von Zeichen, z.B.: [yYjJ] [a-z0-9] \d n Alternativen, durch | markiert, z.B.: /quit|exit/ n Beginn und -ende (^ und $) und andere Begrenzer n Durch Klammerung (...) markierte Unterausdrücke n Wiederholungsfaktoren ? + {n} {min,max} n das beliebige Zeichen. (nicht \n, siehe Option s) n Assertions (erfüllte Bedingungen), beginnen mit (?
Kommentare n Reguläre Ausdrücke relativ unleserlich n Möglichkeit der Kommentierung mit (?# das ist ein Kommentar) n Verwendung von Option x u Leerraum wird ignoriert, Kommentare wie gewohnt mit # möglich m { a|b# eine Alternative, a oder b }x
Klassen von Zeichen n Aufzählung: [jJyY] oder [^jJyY] (alles außer jJyY) n Aufzählung mit Bereichen: [a-fA-F] n Metazeichen, die Klasse definieren: \wwordchar [a-zA-Z_0-9]\Wnonword char \ddigit [0-9]\Dnondigit \swhitespace [ \t\n\r\f]\Snon-whitespace n Sonderzeichen: \a \e \f \n \r \t (beep, ESC, formfeed, newline, CR, tab) \033 \x1b \cC (ESC, ESC, CTRL-C)
Wiederholungen n Zeichen (oder Zeichengruppe) kann mit Wiederholungsfaktor versehen werden n *0 oder mehrmals, entspricht {0,} n ?0 oder 1 mal, entspricht {0,1} n +mindestens 1 mal, entspricht {1,} n {min,max}mindestens min, höchstens max mal n {n}entspricht {n,n} n {n,}mindestens n mal
Optionale Ausdrücke n Ausdrücke, die mehrere Möglichkeiten zulassen: u Alternativen mit | u Ausdrücke mit ?, *, +, {min,max} oder {min,} n Bearbeitung von Alternativen von links nach rechts n andere optionale Ausdrücke sooft wie möglich u Ausdrücke sind greedy - gierig, gefräßig n Änderung des Verhaltens durch nachgestelltes ? u optionale Ausdrücke werden zunächst übergangen u non-greedy, auch minimal matching
Maximales Matching Suche in Apfel,Birne,Kirsche,Pflaume /,.*,/ # greedy, maximal matching F Suche nach erstem Komma (5*falsch, 1*wahr) F Suche nach.* (Bis zum Ende wahr, Alternativen) F Suche nach Komma (falsch) F Nimm letzte Alternative (bis m, dann Komma, falsch) F Weiter so (Backtracking), bis Komma gefunden u daher Resultat:,Birne,Kirsche,
Minimales Matching n Suche in Apfel,Birne,Kirsche,Pflaume /,.*?,/ # non greedy, minimal matching F Suche nach erstem Komma (5*falsch, 1*wahr) F Übergehe.*, suche nach Komma (falsch) F Nimm letzte Alternative (., weiter mit Komma, falsch) F Weiter so (5 mal) bis Komma gefunden u daher Resultat:,Birne, /,[^,]*,/ # non greedy, schnellste Suche F Ausdruck fast immer wahr, kommt schnell zum Ende
Backtracking Probleme n Regex arbeitet stur nach vorgenannten Regeln n Bei geschachtelten optionalen Ausdrücken Gefahr: u (\d+)*a#Suche z.B. nach 17a u String aus 80 Ziffern: + führt zu 80, 79,... Zeichen u * führt zu 80,79,... mal 1 Zeichen + 40,39,... mal 2... u Regex muß immer weitermachen, da a fehlt u Exponentielle Suche mit riesiger Rechenzeit für einfaches Problem n keine geschachtelte optionale (auch |) Ausdrücke!
Subpatterns n Definiert durch runde Klammern um Teilausdrücke n Innerhalb des Regex Rückbezug mit \1 \2.. möglich n Nach erfolgreichem Match als $1 $2.. gefüllt n Gilt nicht für Assertions (?...) (siehe später) n Besonders: (?:) wirkt wie (), aber kein Rückbezug /,(.*?),(.*?),(.*?)/;# $1=Apfel,$2=Birne s/^([^ ]*) *([^ ]*)/$2 $1/;# swap words
Die Variablen $`, $& und $ n Enthalten String, in dem gesucht wird: u $`:vorderer Teil, der nicht gematcht hat u $&:Teil, auf den der Regex paßt u $´:Rest des Strings n Variablen werden nur gefüllt, wenn auch benutzt u einmalige Benutzung triggert Füllung überall
Assertions n Ausdrücke, die erfüllt werden müssen (Länge 0!) n Einfachste Assertions:^ und $ (oder \A und \Z) n Weitere Assertions: \bWortgrenze (zwischen \w und \W) \Bkeine Wortgrenze n Nicht besprochen: lookahead assertion(?=...)(?!...) lookbehind assertion (5.005)(?<=...)(?<!...) und andere Exoten für obfuscated perl contest
Optionen n Strings mit Newlines: u.* endet bei \n, da \n nicht in. F Änderung durch Option s:. erfaßt auch newline u ^ und $ nur am Stringanfang und -ende wahr F mit Option m ^ und $ auch an Zeilenanfang/ende wahr n Ignorieren von Klein/Großschreibung: Option i n Wiederholen von Suchen/Ersetzen: Option g u dann Resultat = Anzahl erfolgreicher Operationen u im Listkontext Resultat = gefundene/ersetzte Strings
Regex in split n split ist die einzige weitere Funktion mit Regex split pattern, string u zerlegt String gemäß pattern pattern ist regex oder /regex/, nicht regex u pattern, das matcht, zerlegt String in = split //, ; zusätzliche Elemente aus () Ausdrücken erzeugt u Verarbeitung von Config-files (key = val Zeilen) %conf = split /\s*=\s*(\S+)\n/, $zeilen);
Hausaufgaben Schreibe ein Programm, das die Zeile abc x10 mit folgenden Methoden zerlegt: substr, pack, regex, split n Übe die Benutzung von substr als lvalue (links von =) n Entferne Leerzeichen am Stringanfang und -ende (Idiom!) n Schreibe einen regex Ausdruck mit Kommentaren n Übe die Benutzung von $`, $&, $ und $1, $2,… n Wieviele Teste sind in den Beispielen auf S. 12/13 nötig n Wie funktioniert das letzte Beispiel auf S.19 n Lies die manpage perlre