# Mehr zur Zeichensuche

- Optionen beim Suchoperator
- Optionen innerhalb eines regulären Ausdrucks
- Spezielle Variablen
- Suchen und Ersetzen

## Optionen beim Suchoperator

Das Verhalten bei der Suche kann durch nachgestellte Optionen beeinflußt werden:

- `g` ("global")

  Während standardmäßig die Suche beim ersten Treffer abgebrochen wird, veranlaßt diese Option die Ausgabe einer Liste von Lösungen, so als würde man die Stelle nach einem gefundenen Substring als Startpunkt für eine erneute Suche verwenden.

  Beispiel:

  `#!/usr/local/bin/perl -w use strict; my $t = "123-456-789"; my @a = ($t =~ /[1-9]{3}/g); # Suche nach Zifferntripel foreach my $x (@a) { print "$x " } print "\n"; foreach my $x ($t =~ /[1-9]{3}/g) { print "$x " } print "\n"; while($t =~ /[1-9]{3}/g) { print "$& " } print "\n";`

  `123 456 789 123 456 789 123 456 789`

  Der erste Teil zeigt, wie die Suchoperation eine Liste aller gefundenen Substrings zurückgibt. Anstelle der Zuweisung zu einem Array kann auch `foreach` direkt die Lösungsliste durchlaufen. Sehr häufig verwendet man auch die dritte dargestellte Methode: schrittweises Durchsuchen der Zeichenkette mittels einer `while`-Schleife.

  Es ist zu beachten, daß die Suche nach einer weiteren Lösung jeweils hinter dem zuvor gefundenen Muster beginnt. Daher gibt folgendes Skript nur die eine Lösung "`-ab-`" aus (und nicht noch "`-cd-`" zusätzlich).

  `#!/usr/local/bin/perl -w use strict; my $t = "-ab-cd-"; foreach($t =~ /-[a-z][a-z]-/g) { print "$_ " }`

- `i` ("case-insensitive")

  Verwendet man diese Option, wird bei der Suche nach Buchstaben nicht zwischen Groß- und Kleinschreibung unterschieden (dies funktioniert auch bei nationalen Sonderzeichen wie den deutschen Umlauten sofern das Betriebssystem die entsprechende Sprachumgebung unterstützt).

  Beispiel:

  `#!/usr/local/bin/perl -w use strict; my $t = "Ähnlichkeit"; if($t =~ /ähn/) { print "wahr\n" } else { print "falsch\n" } if($t =~ /ähn/i) { print "wahr\n" } else { print "falsch\n" }`

  `falsch wahr`

- `s` ("single line")

  Hiermit wird eine Zeichenkette als einzelne Zeile betrachtet, auch wenn sie Zeilenvorschübe ("`\n`") enthält. Dadurch entfällt dann in einem Suchmuster die Sonderrolle von "`\n`" bezüglich des Punktes ("`.`"), der sonst nur auf alle anderen Zeichen, nicht aber den Zeilenvorschub, paßt.

  Beispiel:

  `#!/usr/local/bin/perl -w use strict; my $t = "AAA\nBBB\n"; if($t =~ /A.B/) { print "wahr\n" } else { print "falsch\n" } if($t =~ /A.B/s) { print "wahr\n" } else { print "falsch\n" }`

  `falsch wahr`

- `m` ("multiple lines")

  Verwendet man diese Option, so passen die Ankerpunkte "`^`" und "`$`" nicht nur am Anfang bzw. Ende der vorgegebenen Zeichenkette, sondern auch an jedem Zeilenanfang und -ende. Um einen Ankerpunkt an den Anfang oder das Ende des untersuchten Strings zu setzen, muß in diesem Falle "`\A`" bzw. "`\Z`" verwendet werden.

  Beispiel:

  `#!/usr/local/bin/perl -w use strict; my $t = "Kugel 1\nPyramide 2\nQuader 3\n"; my @a = ($t =~ /^\w+/g); foreach (@a) { print "1) $_\n" } @a = ($t =~ /^\w+/gm); foreach (@a) { print "2) $_\n" }`

  `1) Kugel 2) Kugel 2) Pyramide 2) Quader`

- `o` ("compile once")

  Diese Option dient der Optimierung der Mustersuche (hinsichtlich der Geschwindigkeit) und sollte nur verwendet werden, wenn dies unbedingt nötig ist. Ihre Wirkung besteht darin, daß eine Variablenersetzung im Suchmuster nur einmal zu Beginn stattfindet. Daher muß sichergestellt sein, daß sich die entsprechenden Variablen während der Suche nicht ändern.

  Beispiel:

  `#!/usr/local/bin/perl -w use strict; my $t = "123..abc...456"; my $muster = '0-9'; while($t =~ /[$muster]+/g) { $muster = 'a-z'; # Zeichenklasse ändern print "1) $&\n"; } $muster = '0-9'; while($t =~ /[$muster]+/go) { $muster = 'a-z'; # hier wirkungslos print "2) $&\n"; }`

  `1) 123 1) abc 2) 123 2) 456`

  Hier sieht man nebenbei, daß Suchmuster durchaus auch in Variablen gespeichert werden können.

- `x` ("extended")

  Um komplizierte reguläre Ausdrücke übersichtlicher darstellen zu können, gibt es die Option "`x`", die es ermöglicht, Ausdrücke auf mehrere Zeilen zu verteilen und (normale) Perl-Kommentare einzufügen.

  Beispiel:

  `#!/usr/local/bin/perl -w use strict; my $t = '...<IMG SRC="pfad/bild.gif" WIDTH=110>...'; $t =~ /<IMG # HTML-Tag für Bild (Beginn) \s+ # Leerzeichen SRC=" # Hier kommt der URL (.+?) # Diesen Pfad suchen wir " # Ende des URL .*? # vielleicht noch Optionen > # Ende des HTML-Tags /ix; # case-insensitive, extended print "$1\n";`

  `pfad/bild.gif`

[Seitenanfang]

## Optionen innerhalb eines regulären Ausdrucks

Die im vorherigen Abschnitt beschriebenen global wirkenden Optionen können auch innerhalb eines regulären Ausdrucks gesetzt werden, um beispielsweise nur Teile davon zu beeinflussen. Dies wird durch "`(?`Option(en)`)`" bewerkstelligt. Hierbei können die Optionen `i`, `m`, `s` und `x` verwendet werden. Die Wirkung erstreckt sich bis zum Ende des regulären Ausdrucks, innerhalb einer Gruppierung oder bis zu einer Deaktivierung mittels "`(?-`Option(en)`)`".

`#!/usr/local/bin/perl -w use strict; my $t = "ABcd"; $t =~ /[a-z][a-z]/i; print "$&\n"; # 1 $t =~ /(?i)[a-z][a-z]/; print "$&\n"; # 2 $t =~ /((?i)[a-z])[a-z]/; print "$&\n"; # 3 $t =~ /[a-z](?i)[a-z]/; print "$&\n"; # 4 $t =~ /(?i)[a-z](?-i)[a-z]/; print "$&\n"; # 5`

`AB AB Bc cd Bc`

Test 2 ist äquivalent zu Test 1. In Test 3 ist wegen der Klammerung nur für den ersten Buchstaben Großschrift erlaubt. Da in Test 4 der erste Buchstabe klein geschrieben sein muß, kommt nur "`cd`" als Lösung infrage. Die letzte Zeile zeigt wie man eine Option wieder abschalten kann (entspricht Test 3).

[Seitenanfang]

## Spezielle Variablen

In den vorherigen Abschnitten wurden schon einige spezielle Perl-Variablen im Zusammenhang mit der Mustersuche erwähnt; hier eine Übersicht:

- `$&` gibt das gefundene Muster zurück
- `$1,$2,$3,...` enthält das Muster der 1.,2.,3.,... runden Klammer
- `$+` enthält das Muster der letzten runden Klammer
- `$`` enthält die Zeichenkette, die vor dem gefundenen Muster steht
- `$'` enthält die Zeichenkette, die hinter dem gefundenen Muster steht

Beispiel:

`#!/usr/local/bin/perl -w use strict; my $s = "Dies ist ein Test ..."; if($s =~ /is([a-z]) (.*) Test/) { print $&."\n"; print $1."\n"; print $2."\n"; print $+."\n"; print $`."\n"; print $'."\n"; }`

`ist ein Test t ein ein Dies ...`

[Seitenanfang]

## Suchen und Ersetzen

Anstelle einer einfachen Suche kann man in Perl auch den gefundenen Ausdruck direkt durch einen neuen ersetzen. Allgemein:

> `$string =~ s/`Regexp`/`Ersatz`/`Optionen`;`

Dabei wird wie beim Suchoperator ("`m/.../`") `$string` nach einer zu Regexp passenden Zeichenkette durchsucht. Wird ein solcher Teilstring gefunden, so wird an dessen Stelle der Text Ersatz gesetzt.

Beispiel:

`#!/usr/local/bin/perl -w use strict; my $t = "Beispiel"; $t =~ s/e/-e-/; print "$t\n";`

`B-e-ispiel`

Im obigen Beispiel wird der String `$t` nach dem Buchstaben "`e`" abgesucht und (beim ersten Auffinden) durch die Zeichenkette "`-e-`" ersetzt.

Auch beim Suchen und Ersetzen können die Schrägstriche des Operators durch andere Zeichen ersetzt werden (keine alphanumerischen Symbole oder Leerzeichen).

Es können die gleichen Optionen wie beim Suchoperator verwendet werden, ihre Wirkung bezieht sich dabei auf den regulären Ausdruck. Eine zusätzliche Option ermöglicht die Auswertung des Ersatz-Teils.

Optionen:

- `g` ("global")

  (siehe Optionen beim Suchoperator)

- `i` ("case-insensitive")

  (siehe Optionen beim Suchoperator)

- `s` ("single line")

  (siehe Optionen beim Suchoperator)

- `m` ("multiple lines")

  (siehe Optionen beim Suchoperator)

- `o` ("compile once")

  (siehe Optionen beim Suchoperator)

- `x` ("extended")

  (siehe Optionen beim Suchoperator)

- `e` ("evaluate")

  Diese Option bewirkt, daß beim Ersetzen der einzusetzende Ausdruck wie ein Befehl in Perl behandelt und ausgewertet wird. Dies kann sogar mehrfach geschehen.

  Beispiel:

  `#!/usr/local/bin/perl -w use strict; my $t = "5+7"; $t =~ s|^(\d+)\+(\d+)$|$1+$2|e; # hier '|' statt '/' print "$t\n\n"; $t = '_x_'; (my $s = $t) =~ s/x+/'"m" x 3' x 1/; print "$s\n"; ($s = $t) =~ s/x+/'"m" x 3' x 1/e; print "$s\n"; ($s = $t) =~ s/x+/'"m" x 3' x 1/ee; print "$s\n";`

  `12 _'"m" x 3' x 1_ _"m" x 3_ _mmm_`

[Seitenanfang]

Autor: Eike Grote | Version: 2.05 (24.1.2012)