Einführung
Reguläre Ausdrücke werden verwendet, um Textmuster zu beschreiben,
nach welchen dann gesucht wird. 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.
Einfache Treffer
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 dieses Sequenz im zu durchsuchenden
String (Ziel-String).
Also findet das (Muster = reguläre Ausdruck) bluh
genau die Sequenz bluh irgendwo im Ziel-String.
Damit Du Zeichen, die üblicherweise als Metazeichen oder Escape-Sequenzen
dienen, als ganz normale Zeichen ohne jede Bedeutung finden kannst,
stelle so einem Zeichen einen \
voran.
Diese Technik nennt man Escaping. Ein Beispiel: das Metazeichen
^
findet den Anfang des Ziel-String, aber \^
findet das Zeichen ^ (Circumflex), \\
findet also \ etc.
Beispiele:
foobar
findet den String foobar
\^FooBarPtr
findet den String ^FooBarPtr
Escape-Sequenzen
Zeichen können auch angeben werden mittels einer Escape-Sequenz, in der Syntax.
\n
findet eine neue Zeile, \t
einen Tabulator etc.
Etwas allgemeiner: \xnn
, wobei nn ein String aus hexadezimalen
Ziffern ist, findet das Zeichen, dessen ASCII Code gleich nn
ist.
Falls Du Unicode-Zeichen (16 Bit kodierte Zeichen) angeben möchtest, dann benutze
\x{nnnn}
, wobei nnnn
– eine oder mehrere hexadezimale Ziffern sind.
\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)
\t
ein Tabulator (HT/TAB), gleichbedeutend wie \x09
\n
Zeilenvorschub (NL), gleichbedeutend wie \x0a
\r
Wagenrücklauf (CR), gleichbedeutend wie \x0d
\f
Seitenvorschub (FF), gleichbedeutend wie \x0c
\a
Alarm (bell) (BEL), gleichbedeutend wie \x07
\e
Escape (ESC), gleichbedeutend wie \x1b
Beispiele:
foo\x20bar
findet foo bar (beachte das Leerzeichen in der Mitte)
\tfoobar
findet foobar, dem unmittelbar ein Tabulator vorangeht
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 und z inklusive.
Falls das Zeichen – selbst ein Mitglied der Zeichenklasse sein soll,
dann setze es als erstes oder letztes Zeichen in die Liste oder schütze
es mit einem vorangestellten \
(escaping). Wenn das Zeichen ]
ebenfalls Mitglied der Zeichenklasse sein soll, dann setze es als erstes Zeichen
in die Liste oder escape es.
Beispiele:
[-az]
findet a, z und –.
[az-]
findet a, z und –.
[a\-z]
findet a, z und –.
[a-z]
findet alle 26 Kleinbuchstaben von a bis z.
[\n-\x0D]
findet eines der Zeichen, #10, #11, #12 oder #13.
[\d-t]
findet irgendeine Ziffer, – oder t.
[]-a]
findet irgendein Zeichen von ]..a.
Metazeichen sind Zeichen mit speziellen Bedeutungen und es gibt verschiedene Arten von Metazeichen.
Sie sind die Essenz der regulären Ausdrücke.
Metazeichen – Zeilen-Separatoren
^
Beginn einer Zeile
$
Ende einer Zeile
\A
Start mit Text
\Z
Endet mit Text
.
irgendein beliebiges Zeichen
Beispiele:
^foobar
findet den String foobar nur, wenn es am Zeilenanfang vorkommt
foobar$
findet den String foobar nur, wenn es am Zeilenende vorkommt
^foobar$
findet den String foobar nur, wenn er der einzige String in der Zeile ist
foob.r
findet Strings wie foobar, foobbr, foob1r etc.
Standardmäßig garantiert das Metazeichen ^
nur, dass das
Suchmuster sich am Anfang des Ziel-String befinden muss, oder am Ende
des Ziel-String mit dem Metazeichen $
. Kommen im Ziel-String Zeilen-Separatoren
vor, so werden diese von ^
oder $
nicht gefunden.
Du kannst allerdings den Ziel-String als mehrzeiligen Puffer behandeln,
so dass ^
die Stelle unmittelbar nach, und ” die Stelle unmittelbar vor
irgendeinem Zeilen-Separator findet.
Du kannst diese Art der Suche einstellen mit dem Modifikator /m
.
Der \A
und \Z
so wie ^
und $
,
außer dass sie nicht übereinstimmen mehrfach, wenn der Modifikator
/m
verwendet wird, während ^
und $
bei jedem Fund wird interne Zeilen-Separator.
Das .
Metazeichen findet Standardmäßig irgendein beliebiges Zeichen,
also auch Zeilen-Separatoren. Wenn Du den Modifikator /s
ausschaltest,
dann findet .
keine Zeilen-Separatoren mehr.
Siehe Zeilen-Separatoren:
http://www.unicode.org/unicode/reports/tr18/
^
ist am Anfang des Eingabestrings, und falls der Modifikator
/m
gesetzt ist, auch unmittelbar folgend einem Vorkommen von
\x0D\x0A
oder \x0A
or \x0D
(falls Du die Unicode-Version benutzt, dann auch nach \x2028
oder
\x2029
oder \x0B
oder \x0C
oder \x85
).
Beachte, dass es keine leere Zeile gibt in der Sequenz \x0D\x0A
.
Diese beiden Zeichen werden atomar behandelt.
$
ist am Anfang des Eingabestrings, und, falls der Modifikator
/m
gesetzt ist, auch unmittelbar vor einem Vorkommen von
\x0D\x0A
oder \x0A
or \x0D
(falls Du die Unicode-Version benutzt, dann auch vor \x2028
oder
\x2029
oder \x0B
oder \x0C
oder \x85
).
Beachte, dass es keine leere Zeile gibt in der Sequenz \x0D\x0A
.
Diese beiden Zeichen werden atomar behandelt.
.
findet ein beliebiges Zeichen. Wenn Du aber den Modifikator
/s
ausstellst, dann findet . keine Zeilen-Separatoren
\x0D\x0A
und \x0A
und \x0D
mehr
(falls Du die Unicode-Version benutzt, dann auch \x2028
und
\x2029
und \x0B
und \x0C
and \x85
).
Beachte, dass ^.*$
(was auch eine leere Zeile findet können sollte)
dennoch nicht den leeren String innerhalb der Sequenz \x0D\x0A
findet,
aber es findet den Leerstring innerhalb der Sequenz \x0A\x0D
.
Die Behandlung des Zielstring als mehrzeiliger String kann leicht Deinen
Bedürfnissen angepasst werden dank der Eigenschaften LineSeparators und LinePairedSeparator.
Du kannst nur den UNIX-Stil Zeilen-Separator \n
benutzen
oder nur DOS-Stil Separatoren \r\n
oder beide gleichzeitig
(wie schon oben beschrieben und wie es als Standard gesetzt ist).
Du kannst auch Deine eigenen Zeilen-Separatoren definieren!
Metazeichen – vordefinierte Klassen
\w
ein alphanumerisches Zeichen inklusive _
\W
kein alphanumerisches Zeichen, auch kein _
\d
ein numerisches Zeichen
\D
kein numerisches Zeichen
\s
irgendein Wörter trennendes Zeichen (entspricht [ \t\n\r\f])
\S
kein Wörter trennendes Zeichen
Du kannst \w
, \d
und \s
innerhalb
Deiner selbst definierten Zeichenklassen benutzen.
Beispiele:
foob\dr
findet Strings wie foob1r, foob6r etc.,
aber nicht foobar, foobbr etc.
foob[\w\s]r
findet Strings wie foobar, ‘foob r’, ‘foobbr’ etc.,
aber nicht foob1r, foob=r etc.
Benutze die Eigenschaften SpaceChars und WordChars,
um die Zeichenklassen \w
, \W
,
\s
, \S
zu definieren.
Somit kannst Du sie auch leicht umdefinieren.
Metazeichen – Wortgrenzen
\b
findet eine Wortgrenze
\B
findet alles außer einer Wortgrenze
Eine Wortgrenze \b
is der Ort zwischen zwei Zeichen,
welcher ein \w
auf der einen und ein \W
auf der
anderen Seite hat bzw. umgekehrt.
\b
bezeichnet alle Zeichen des \w
bis vor das
erste Zeichen des \W
bzw. umgekehrt.
Metazeichen – Iteratoren
Jeder Teil eines regulären Ausdruckes kann gefolgt werden von einer anderen
Art von Metazeichen – den Iteratoren.
Dank dieser Metazeichen kannst Du die Häufigkeit des Auftretens des Suchmusters
im Zielstring definieren. Dies gilt jeweils für das vor diesem Metazeichen
stehenden Zeichen, das Metazeichen oder den Teilausdruck.
*
kein- oder mehrmaliges Vorkommen gierig
, gleichbedeutend wie {0,}
+
ein- oder mehrmaliges Vorkommen gierig
, gleichbedeutend wie {1,}
?
kein- oder einmaliges Vorkommen gierig
, gleichbedeutend wie {0,1}
{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 genügsam
, gleichbedeutend wie {0,}?
+?
ein oder mehrmaliges Vorkommen genügsam
, gleichbedeutend wie {1,}?
??
kein- oder einmaliges Vorkommen genügsam
, gleichbedeutend 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
Also, die Ziffern in den geschweiften Klammern in der Form
{n,m}
geben an, wie viele 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 Limiten 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 es wie ein normales Zeichen
behandelt.
Beispiele:
foob.*r
findet Strings wie foobar, foobalkjdflkj9r und foobr
foob.+r
findet Strings wie foobar
, foobalkjdflkj9r
, aber nicht foobr
foob.?r
findet Strings wie foobar
, foobbr
und foobr
, aber nicht foobalkj9r
fooba{2}r
findet den String foobaar
fooba{2,}r
findet Strings wie foobaar
, foobaaar
, foobaaaar
etc.
fooba{2,3}r
findet Strings wie foobaar
, or foobaaar
, aber nicht foobaaaar
Eine kleine Erklärung zum Thema
gierig
oder
genügsam
.
Gierig
nimmt soviel wie möglich,
wohingegen genügsam
bereits mit dem ersten Erfüllen
des Suchmusters 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.
Du kannst alle Iteratoren auf den genugsamen Modus umschalten mit
dem Modifier /g
.
Metazeichen – Alternativen
Du kannst eine Serie von Alternativen für eine Suchmuster
angeben, indem Du diese mit einem |
trennst. Auf
diese Art findet das Suchmuster fee|fie|foe
eines
von fee, fie, oder foe im
Zielstring. Dies würde auch mit f(e|i|o)e
erreicht.
Die erste Alternative beinhaltet alles vom letzten Muster-Limiter
((
, [
oder natürlich der Anfang des
Suchmusters) bis zum ersten |
. Die letzte
Alternative beinhaltet alles vom letzten |
bis zum
nächsten Muster-Limiter. Aus diesem Grunde ist es allgemein eine
gute Gewohnheit, die Alternativen in Klammern anzugeben, um
möglichen Missverständnissen darüber vorzubeugen, wo die
Alternativen beginnen und enden.
Alternativen werden von links nach rechts
gepürft, so dass der T reffer im Zielstring zusammengesetzt ist
aus den jeweils zuerst passenden Alternativen. 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.
Erinnere Dich auch daran, dass das |
innerhalb von
eckigen Klammern wie ein normales Zeichen behandelt wird, so dass
[fee|fie|foe]
dasselbe bedeutet wie
[feio|]
.
Beispiele:
foo(bar|foo)
findet die Strings foobar
oder foofoo.
Metazeichen – Teilausdrücke
Das Klammernkonstrukt (...)
wird auch dazu
benutzt, reguläre Teilausdrücke zu definieren. Nach dem Parsen
findest Du Positionen, Längen und effektive Inhalte der regulären
Teilausdrücke in den TRegExpr-Eigenschaften MatchPos,
MatchLen und Match. Und kannst sie ersetzen mit
den Template-Strings in TRegExpr.Substitute.
Teilausdrücke werden nummeriert von links nach
recht, jeweils in der Reihenfolge ihrer öffnenden
Klammer. Der erste Teilausdruck hat die Nummer 1, der gesamte
reguläre Ausdruck hat die Nummer 0. Der gesamte Ausdruck kann
ersetzt werden in TRegExpr.Substitute als $0
oder
$&
.
Beispiele:
(foobar){8,10}
findet das 8.-, das
9-. oder das 10.- Vorkommen / Strings. Die
Strings beinhalten foobar.
foob([0-9]|a+)r
findet foob0r,
foob1r, foobar, foobaar,
foobaar etc.
Metazeichen – Rückwärts-Referenzen
Die Meta-Character \1
bis \9
werden
in Suchmustern interpretiert als Rückwärts-Referenzen.
\<n>
findet einen zuvor bereits gefundenen
Teilausdruck #<n>
.
Beispiele:
(.)\1+
findet aaaa und cc.
(.+)\1+
findet auch abab und 123123.
(['"]?)(\d+)\1
findet 13 (innerhalb “), oder 4
(innerhalb ‘) oder auch 77, etc.
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 eingebettet werden im
Suchmuster des regulären Ausdruckes mittels des Konstruktes
(?...)
.
Du kannst allerdings auch die meisten Modifikatoren
beeinflussen, indem Du den entsprechenden TRegExpr-Eigenschaften
die passenden Werte zuweist.
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
Führe die Suche Schreibweisen-unabhägig durch, allerdings
abhängig von den Einstellungen in Deinem System, Lokale
Einstellungen. Beachte auch die InvertCase.
m
Behandle den Zielstring als mehrzeiligen String. Das bedeutet,
ändere die Bedeutungen von ^
und $
:
Statt nur den Anfang oder das Ende des Zielstring zu finden, wird
jeder Zeilen Separator innerhalb eines Strings erkannt.
Beachte auch die Zeilen-Separatoren.
s
Behandle den Zielstring als einzelne Zeile. Das bedeutet, dass
.
jedes beliebige Zeichen findet, sogar
Zeilen-Separatoren. Beachte auch Zeilen-Separatoren,
die es normalerweise nicht findet.
g
Modifikator für den Genügsam
-Modus. Durch das
Ausstellen werden alle folgenden Operatoren in den
Genügsam
-Modus. Standardmassig sind alle Operatoren
gierig
. Wenn also der Modifikator
/g
aus ist, dann arbeitet +
wie
+?
, *
als *?
etc.
x
Erweitert die Lesbarkeit des Suchmusters durch
Whitespace und Kommentare,
Beachte die Erklärung unten.
r
Modifikator. Falls er gesetzt ist, beinhaltet die Zeichenklasse
à-ÿ
zusätzliche Russische Buchstaben
¸
, À-ß
beinhaltet zusätzlich
¨
, und à-ß
beinhaltet alle
Russische Symbole.
Sorry für fremdsprachliche Benutzer, er ist gesetzt
Standardmäßig. Falls Du ihn ausgeschaltet haben willst
Standardmäßig, dann setze die globale Variable
TRegExprModifierR auf false.
Der Modifikator /x
selbst braucht etwas mehr
Erklärung. Er sagt TRegExpr, dass er allen Whitespace
ignorieren soll, der nicht escaped oder innerhalb einer
Zeichenklasse ist. Du kannst ihn benutzen, um den regulären
Ausdruck in kleinere, besser lesbare Teile zu zerlegen. Das
Zeichen #
wird nun ebenfalls als Metazeichen
behandelt und leitet einen Kommentar bis zum Zeilenende ein.
Beispiel:
(
(abc) # Kommentar 1
| # Du kannst Leerschläge zur Formatierung benutzen - TRegExpr
ignoriert sie
(efg) # Kommentar 2
)
Dies bedeutet auch, wenn Du echten Whitespace oder das
#
im Suchmuster haben möchtest. Außerhalb einer
Zeichenklasse, wo sie unbehelligt von /x
sind, dann
muss der entweder escaped oder mit der hexadezimalen Schreibweise
angegeben werden. Beides zusammen sorgt dafür, dass reguläre
Ausdrücke besser lesbar werden.
(?imsxr-imsxr)
Dies kann benutzt werden in Regulären Ausdrücken, um
Modifikatoren innerhalb eines Ausdruckes im Flug zu ändern. Wenn
dieses Konstrukt innerhalb eines Teilausdruckes erscheint,
betrifft er auch nur diesen.
Beispiele:
(?i)Saint-Petersburg
findet Saint-petersburg und Saint-Petersburg
(?i)Saint-(?-i)Petersburg
findet Saint-Petersburg, aber nicht Saint-petersburg
(?i)(Saint-)?Petersburg
findet Saint-petersburg und saint-petersburg
((?i)Saint-)?Petersburg
findet saint-Petersburg, aber nicht saint-petersburg
(?#text)
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.