Personal Backup Vers. 4 und 5 |
|
| © 2010, J. Rathlev, IEAP, Uni-Kiel |
Leider ist die Homepage der Delphi-Bibliothek für Reguläre Ausfrücke (TRegExp) von Andrey V. Sorokin und damit auch die dort früher bereitgestellten Informationen nicht mehr erreichbar. Daher habe ich überarbeitete deutsche Übersetzung der originalen Hilfe-Datei in die Dokumentation von Personal Backup eingefügt.
Im Programm können reguläre Ausdrücke für die Filterung von Ordnernamen, Dateinamen und Erweiterungen verwendet werden. Dabei gibt es unterschiedliche Voreinstellungen:
Mit dem Modifikator i kann diese Einstellung bei Bedarf angepasst werden.
Außerdem gibt es Unterschiede zwischen den Versionen 4 und 5. Personal Backup 5 verwendet TRegExp in der Unicode-Version
Reguläre Ausdrücke sind eine weitverbreitete Methode, um Textmuster zu beschreiben, nach denen gesucht werden soll. Spezielle Metazeichen erlauben das Definieren von Bedingungen, beispielsweise soll ein bestimmter gesuchter String am Anfang oder am Ende einer Zeile vorkommen, oder ein bestimmtes Zeichen soll n-mal Vorkommen.
Reguläre Ausdrücke sehen üblicherweise für Anfänger ziemlich kryptisch aus, sind aber im Grunde genommen recht einfache (wenn man das Prinzip verstanden hat), aber enorm mächtige Werkzeuge.
Jedes einzelne Zeichen findet sich selbst, außer es sei ein Metazeichen mit einer speziellen Bedeutung (siehe weiter unten).
Eine Sequenz von Zeichen findet genau diese Sequenz im zu durchsuchenden String (Zielstring). Also findet das Muster (= reguläre Ausdruck) "bluh" genau die Sequenz "bluh" irgendwo im Zielstring. Soweit ist das noch ganz einfach.
Damit man Zeichen, die üblicherweise als Metazeichen oder Escape-Sequenzen dienen, als ganz normale Zeichen ohne jede Bedeutung finden kann, stelle man solch einem Zeichen ein "\" voran. Diese Techninik nennt man Escaping. Ein Beispiel: das Metazeichen "^" findet den Anfang des Zielstrings, aber "\^" findet das Zeichen "^" (Circumflex), "\\" findet also "\" etc.
Zeichen können auch mittels einer Escape-Sequenz angeben werden. Die Syntax
ähnelt derer, wie sie in C oder Perl verwendet wird:
"\n" findet eine neue Zeile, "\t" einen Tabulator etc.
Für beliebige ASCII-Zeichen gibt man "\xnn" an, wobei nn ein String aus hexadezimalen
Ziffern ist. Es wird das Zeichen gefunden, dessen ASCII Code gleich nn ist.
Bei Unicode-Zeichen (16 Bit kodierte Zeichen) benutzt man '\x{nnnn}', wobei 'nnnn' –
eine oder mehrere hexadezimale Ziffern sind.
| Code | Beschreibung | Äquivalenz |
| \t | Tabulator (HT/TAB) | \x09 |
| \n | Zeilenvorschub (LF) | \x0a |
| \r | Wagenrücklauf (CR) | \x0d |
| \f | Seitenvorschub (FF) | \x0c |
| \a | Alarm (bell) (BEL) | \x07 |
| \e | Escape (ESC) | \x1b |
| \xnn | Zeichen mit dem Hex-Code nn (ASCII-Text) | |
| \x{nnnn} | Zeichen mit dem Hex-Code nnnn (ein Byte für ASCII-Text und zwei Bytes für Unicode-Zeichen |
Man kann sogenannte Zeichenklassen definieren, indem man eine Liste von Zeichen, eingeschlossen in eckige Klammern [], angibt. Solch eine Zeichenklasse findet genau eines der aufgelisteten Zeichen im Zielstring.
Falls das erste aufgelistete Zeichen, das direkt nach dem "[", ein "^" ist, findet die Zeichenklasse jalle Zeichen ausser denjenigen in der Liste.
Innerhalb der Liste kann das Zeichen "-" benutzt werden, um einen Bereich oder eine Menge von Zeichen zu definieren. So definiert a-z alle Zeichen zwischen "a" and "z" inklusive.
Falls das Zeichen "-" selbst ein Mitglied der Zeichenklasse sein soll, dann setz man es als erstes oder letztes Zeichen in die Liste oder schützt es mit einem vorangestellten "\" (escaping). Wenn das Zeichen "]" ebenfalls Mitglied der Zeichenklasse sein soll, dann setzt man es als erstes Zeichen in die Liste oder als "\]".
Metazeichen sind Zeichen mit speziellen Bedeutungen. Sie sind die Essenz der regulären Ausdrücke. Es gibt verschiedene Arten von Metazeichen wie unten beschrieben.
| Code | Beschreibung |
| ^ | Zeilenanfang |
| $ | Zeileende |
| \A | Textanfang |
| \Z | Textende |
| . | ein beliebiges Zeichen |
Standardmässig garantiert das Metazeichen "^" nur, dass das Suchmuster sich am Anfang des Zielstrings befinden muss, oder am Ende des Zielstrings mit dem Metazeichen "$". Kommen im Zielstring Zeilenseparatoren vor, so werden diese von "^" oder "$" nicht gefunden.
Man kann allerdings den Zielstring als mehrzeiligen Puffer behandeln, so dass "^" die Stelle unmittelbar nach, und "$" die Stelle unmittelbar vor irgendeinem Zeilenseparator findet. Diese Art der Suche kann mit dem Modifikator /m eingestellt werden.
\A und \Z funktionieren genau so wie "^" und "$", außer dass sie keine mehrfachen Stellen finden, wenn der Modifikator /m verwendet wird. "^" and "$" dagegen finden die zu suchenden Zeichen an jedem internen Zeilentrenner.
Das "." Metazeichen findet standardmässig alle Zeichen, also auch Zeilenseparatoren. Dies kann mit Auschalten des Modifikators /s verhindert werden.
TRegExpr geht mit Zeilenseparatoren so um, wie es auf www.unicode.org (http://www.unicode.org/unicode/reports/tr18/) empfohlen ist:
"^" ist am Anfang des Eingabestrings, und, falls der Modifikator /m gesetzt ist, auch unmitelbar folgend einem Vorkommen von \x0D\x0A oder \x0A oder \x0D (falls die Unicode-Version von TRegExpr verwendet wird, dann auch nach \x2028 oder \x2029 oder \x0B oder \x0C oder \x85). Zu beachten ist, dass es bei der Sequenz \x0D\x0A keine leere Zeile gibt. Diese beiden Zeichen werden als zusammengehörig behandelt.
"$" ist am Anfang des Eingabestrings, und, falls der Modifikator /m gesetzt ist, auch unmitelbar vor einem Vorkommen von \x0D\x0A oder \x0A or \x0D (falls die Unicode-Version von TRegExpr verwendet wird, dann auch vor \x2028 oder \x2029 oder \x0B oder \x0C oder \x85). Zu beachten ist, dass es bei der Sequenz \x0D\x0A keine leere Zeile gibt. Diese beiden Zeichen werden als zusammengehörig behandelt.
"." findet ein beliebiges Zeichen. Wenn der Modifikator /s ausgeschaltet ist, findet "." allerdings keine Zeilenseparatoren \x0D\x0A und \x0A und \x0D mehr (falls die Unicode-Version von TRegExpr verwendet wird, dann auch \x2028 und \x2029 und \x0B und \x0C and \x85).
Zu beachten ist, dass "^.*$" (was auch eine leere Zeile finden sollte) dennoch nicht den leeren String innerhalb der Sequenz \x0D\x0A findet, wohl aber den Leerstring innerhalb der Sequenz \x0A\x0D.
Die Behandlung des Zielstrings als mehrzeiliger String kann mittels der TRegExpr-Eigenschaften LineSeparators und LinePairedSeparator leicht den erfordelichen Bedürfnissen angepasst werden. Man kann entweder nur den UNIX-Stil- Zeilenseparator \n benutzen, nur die DOS-Stil-Separatoren \r\n oder beide gleichzeitig (wie schon oben beschrieben und wie es als Standard gesetzt ist). Es ist auch möglich, eigene Zeilenseparatoren zudefinieren.
| \w | ein alphanumerisches Zeichen inklusive "_" |
| \W | kein alphanumerisches Zeichen, auch kein "_" |
| \d | ein numerisches Zeichen |
| \D | kein numerisches Zeichen |
| \s | irgendein wörtertrennendes Zeichen (entspricht [ \t\n\r\f]) |
| \S | kein wörtertrennendes Zeichen |
\w, \d und \s dürfen auch innerhalb von selbst definierten Zeichenklassen benutzt werden.
TRegExpr benutzt die Eigenschaften SpaceChars und WordChars, um die Zeichenklassen \w, \W, \s, \S zu definieren. Somit lassen diese sich auch leicht umdefinieren.
| \b | findet eine Wortgrenze |
| \B | findet alles ausser einer Wortgrenze |
Eine Wortgrenze (\b) is der Ort zwischen zwei Zeichen, welcher ein \w auf der einen und ein \W (s.o.) auf der anderen Seite hat bzw. umgekehrt. \b bezeichnet alle Zeichen des \w bis vor das erste Zeichen des \W bzw. umgekehrt.
Jedem Teil eines regulären Ausdruckes kann eine spezielle Art von Metazeichen folgen, ein Iterator. Dank dieser Metazeichen kann die Häufigkeit des Auftretens des Suchmusters im Zielstring definiert werden. Dies gilt jeweils für das vor diesem Metazeichen stehende Zeichen, Metazeichen oder den Teilausdruck.
| {n} | genau n-maliges Vorkommen ("gierig") |
| {n,} | mindestens n-maliges Vorkommen ("gierig") |
| {n,m} | mindestens n-, aber höchstens m-maliges Vorkommen ("gierig") |
| * | kein- oder mehrmaliges Vorkommen ("gierig"), wie {0,} |
| + | ein- oder mehrmaliges Vorkommen ("gierig"), wie {1,} |
| ? | kein- oder einmaliges Vorkommen ("gierig"), wie {0,1} |
| {n}? | genau n-maliges Vorkommen ("genügsam") |
| {n,}? | mindestens n-maliges Vorkommen ("genügsam") |
| {n,m}? | mindestens n-, aber höchstens m-maliges Vorkommen ("genügsam") |
| *? | kein- oder mehrmaliges Vorkommen ("genügsam"), wie {0,}? |
| +? | ein oder mehrmaliges Vorkommen ("genügsam"), wie {1,}? |
| ?? | kein- oder einmaliges Vorkommen ("genügsam"), wie {0,1}? |
Die Ziffern in den geschweiften Klammern in der Form {n,m} geben an, wieviele Male das Suchmuster im Zielstring gefunden muss, um einen Treffer zu ergeben. Die Angabe {n} ist gleichbedeutend wie {n,n} und findet genau n Vorkommen. Die Form {n,} findet n oder mehre Vorkommen. Es gibt keine Beschränkungen für die Zahlen n und m. Aber je grösser sie sind, desto mehr Speicher und Zeit wird benötigt, um den regulären Ausdruck auszuwerten.
Falls eine geschweifte Klammer in einem anderen als dem eben vorgestellten Kontext vorkommt, wird sie wie ein normales Zeichen behandelt.
Eine kleine Erklärung zum Thema "gierig" oder "genügsam":
"Gierig" nimmt soviel wie möglich vom Suchmuster, wohingegen "genügsam" mit so wenig
wie nötig bereits zufrieden ist.
Beispiel: 'b+' und 'b*' angewandt auf den
Zielstring 'abbbbc' findet 'bbbb', 'b+?' findet 'b', 'b*?' findet den leeren
String, 'b{2,3}?' findet 'bb', 'b{2,3}' findet 'bbb'.
Alle Iteratoren können mit dem Modifikator /g auf den genügsamen Modus umgeschaltet werden.
Es gibt eine Reihe von Alternativen für ein Suchmuster, die mit einem "|" voneinander getrennt werden. Auf diese Art findet das Suchmuster "fee|fie|foe" eines von "fee", "fie", oder "foe" im Zielstring. Das Gleiche würde auch mit f(e|i|o)e erreicht.
Die erste Alternative beinhaltet alle Zeichen vom letzten Muster-Begrenzer ("(", "[" oder natürlich der Anfang des Suchmusters) bis zum ersten "|". Die letzte Alternative beinhaltet alles vom letzten "|" bis zum nächsten Muster-Begrenzer. Aus diesem Grunde ist es zu empfehlen, die Alternativen immer in Klammern anzugeben, um möglichen Missverständnissen darüber vorzubeugen, wo die Alternativen beginnen und enden.
Alternativen werden von links nach rechts geprüft, so dass der Treffer im Zielstring aus den jeweils zuerst passenden Alternativen zusammengesetzt ist. Das bedeutet, dass Alternativen nicht notwendigerweise "gierig" sind. Ein Beispiel: Wenn man mit "(foo|foot)" im Zielstring "barefoot" sucht, so passt bereits die erste Variante. Diese Tatsache mag nicht besonders wichtig erscheinen, aber es ist natürlich wichtig, wenn der gefundene Text weiterverwendet wird. Im Beispiel zuvor würde der Benutzer nicht "foot" erhalten, wie er eventuell beabsichtigt hatte, sondern nur "foo".
Man sollte dabei nicht vergessen, dass das "|" innerhalb von eckigen Klammern wie ein normales Zeichen behandelt wird, so dass [fee|fie|foe] dasselbe bedeutet wie [feio|].
Das Klammernkonstrukt (...) wird auch dazu benutzt, reguläre Teilausdrücke zu definieren (nach dem Abnalysieren findet man Positionen, Längen und effektive Inhalte der regulären Teilausdrücke in den TRegExpr-Eigenschaften MatchPos, MatchLen und Match und kann die Schablonen-Ausdrücke in TRegExpr.Substitute durch sie ersetzen).
Teilausdrücke werden von links nach rechts nummeriert, jeweils in der Reihenfolge ihrer öffnenden Klammer. Der erste Teilausdruck hat die Nummer 1. Der gesamte reguläre Ausdruck hat die Nummer 0 und wird in der Ersetzen-Schablone (TRegExpr.Substitute) durch '$0' oder '$&' repräsentiert).
Die Metazeichen \1 bis \9 werden in Suchmustern als Rückwärtsreferenzen interpretiert. \<n> findet einen zuvor bereits gefundenen Teilausdruck #<n>.
Modifikatoren sind dazu da, das Verhalten von TRegExpr zu verändern.
Es gibt viele Wege, die weiter unten beschriebenen Modifikatoren zu nutzen. Jeder der Modifikatoren kann in das Suchmuster des regulären Ausdruckes mittels des Konstruktes (?...) eingebettet werden.
Die meisten Modifikatoren können aber auch durch Setzen der entsprechenden TRegExpr-Eigenschaft auf den gewünschten Wert beeinflusst werden (Beispiel: Zuweisung an ModifierX oder ModifierStr für alle Modifikatoren zugleich).
Die Standardwerte für neue Instanzen von TRegExpr-Objekte sind definiert in globalen Variablen. Beispielsweise definiert die globale Variable RegExprModifierX das Verhalten des Modifikators X und damit die Einstellung der TRegExpr-Eigenschaft ModifierX bei neu instantiierten TRegExpr-Objekten.
(?i)Die Suche erfolgt ohne Berücksichtigung der Groß- und Kleinschreibung (ev. abhängig von den Sprach-Einstellungen des Betriebssystems).
(?-i)Die Suche erfolgt mit Berücksichtigung der Groß- und Kleinschreibung.
(?m)Behandle den Zielstring als mehrzeiligen String, d.h., dass die
Bedeutungen von "^" und "$" sich ändern (s.o).:
Statt nur den Anfang oder das Ende des Zielstrings zu finden, wird jeder Zeilenseparator
innerhalb eines Strings erkannt (siehe auch Zeilenseparatoren)
Behandle den Zielstring als einzelne Zeile., d.h., dass "." jedes beliebige Zeichen findet, auch Zeilenseparatoren), die es normalerweise nicht findet.
(?-g)Dieser (nicht-standard) Modifikator schaltet alle folgenden Operatoren in den "Genügsam"-Modus (standardmassig sind alle Operatoren "gierig" ($g)). Danach arbeitet '+' wie '+?', '*' als '*?' etc.
(?r)Dieser (nicht-standard) Modifikator schaltet in einen speziellen Modus für russische Symbole (normalerweise ausgeschaltet).
(?x)Erweitert die Lesbarkeit des Suchmusters durch Zwischenräume und Kommentare. Er bewirkt, dass alle Zwischenräume, die nicht durch eine Escape-Sequenz oder innerhalb einer Zeichenklasse gekennzeichnet sind, ignoriert werden. Man kann damit den regulären Ausdruck in kleinere, besser lesbare Teile zerlegen. Das Zeichen # wird als Metazeichen behandelt und leitet einen Kommentar bis zum Zeilenende ein.
Beispiel:Wenn man also echte Zwischenräume oder das # im Suchmuster haben will, (ausserhalb einer Zeichenklasse, wo sie durch /x nicht ignoriert werden), muss das entweder als Escape-Sequenz oder int der hexadezimalen Schreibweise angegeben werden. Beides zusammen sorgt dafür, dass reguläre Ausdrücke besser lesbar werden.
Ein Kommentar, der Text wird ignoriert. Beachte, dass TRegExpr den Kommentar abschliesst, sobald er eine ")" sieht. Es gibt also keine Möglichkeit, das Zeichen ")" im Kommentar zu haben.