Reguläre Ausdrücke in Perl (6)

## Ankerpunkte bei der Suche

Ankerpunkte bieten die Möglichkeit festzulegen, daß der gesuchte Substring an einer bestimmten Stelle in der vorgegebenen Zeichenkette auftreten muß.

Soll nach einem Muster nur am Beginn eines Strings gesucht werden, so setze man einen Zirkumflex ("`^`") oder "`\A`" an den Beginn des regulären Ausdrucks. "`^`" und "`\A`" liefern nur unterschiedliche Lösungen, wenn bei dem regulären Ausdruck die Option m (multiple lines) verwendet wird: während "`\A`" sich immer nur auf den Anfang der (eventuell mehrzeiligen) Zeichenkette bezieht, paßt "`^`" auf jedes Symbol, das nach einem newline ("`\n`") steht (d.h., auf jedes Symbol, das an einem Zeilenanfang steht).

Analog erfolgt die Suche am Ende eines Strings: hier sind die Symbole, die am Ende des regulären Ausdrucks stehen, das Dollar-Zeichen ("`$`") bzw. "`\Z`". Auch hier tritt ein Unterschied nur im Zusammenhang mit der Option m zutage: "`\Z`" paßt nur am Ende der gesamten Zeichenkette, "`$`" sucht an jedem einzelnen Zeilenende.

    #!/usr/local/bin/perl -w

    $t = "abrakadabra";

    if($t =~ /^abra/)  { print "true\n" } else { print "false\n" }  # Test 1
    if($t =~ /abra$/)  { print "true\n" } else { print "false\n" }  # Test 2
    if($t =~ /^kada/)  { print "true\n" } else { print "false\n" }  # Test 3
    if($t =~ /^abra$/) { print "true\n" } else { print "false\n" }  # Test 4

Test 1 findet den passenden Substring wie gewüncht zu Beginn von `$t` ('abrakadabra'); ebenso wie Test 2 am Ende fündig wird ('abrakadabra'). Die Suche in Test 3 dagegen bleibt erfolglos; es ist zwar ein Substring 'kada' vorhanden, der steht aber nicht wie gefordert am Anfang von `$t`. Auch Test 4 liefert "`false`"; auch wenn 'abra' sowohl am Anfang als auch am Ende von $t steht, so sind dies doch zwei verschiedene Substrings.

    #!/usr/local/bin/perl -w

    $t = "Erste Zeile\nZweite Zeile\nDritte Zeile\n";

    if($t =~ /\A[\w\s]+?$/m)  { print "true ($&)\n" }  # Test 1
    if($t =~ /\A[\w\s]+?\Z/m) { print "true ($&)\n" }  # Test 2

Hier wird der Unterschied zwischen "`$`" und "`\Z`" deutlich: Während Test 1 als Lösung nur die erste Zeile anbietet (bis zum ersten Zeilenvorschub "`\n`"), steht in der Variablen `$&` nach Test 2 fast der gesamte Vorgabestring (Ausnahme: der letzte Zeilenvorschub in der dritten Zeile).

Anmerkung: Hier wurde zur Suche die Klasse `[\w\s]` (alphanumerische Zeichen und Leerzeichen) verwendet, da ein Punkt ("`.`") nur mit der single line-Option s auch auf einen newline `\n` paßt.

Man beachte, daß diese Ankerpunkte gewissermaßen eine höhere Priorität besitzen als beispielsweise das Alternativ-Symbol ("`|`")

    #!/usr/local/bin/perl -w

    $t = "Mein Computer";

    if($t =~ /^Rechner|Computer$/)   { print "true\n" } else { print "false\n" }  # Test 1
    if($t =~ /^(Rechner|Computer)$/) { print "true\n" } else { print "false\n" }  # Test 2

Test 1 liefert den Wert "`true`", da er 'Computer' am Ende von `$t` findet ("Suche nach 'Rechner' am Anfang oder 'Computer' am Ende"). Test 2 dagegen gibt die Antwort "`false`", da hier der Suchauftrag lautet: "Suche nach 'Rechner' oder 'Computer', die sich von Anfang bis Ende des Strings erstrecken".

Weitere Ankerpunkte können Wortgrenzen sein. Dabei ist eine solche Grenze definiert als der Punkt zwischen einem Zeichen aus der Klasse `\w` und einem aus `\W`. Eine solche Wortgrenze wird durch "`\b`" dargestellt (dabei handelt es sich nicht um ein Zeichen an sich, sondern den Raum zwischen zwei Symbolen!). Das Gegenstück zu "`\b`" ist "`\B`" (Ankerpunkt inner- oder außerhalb eines Wortes).

    #!/usr/local/bin/perl -w

    $t = "Der ASCII-Code";

    if($t =~ /\b[A-Z]/) { print "true ($&)\n" } else { print "false\n" }  # Test 1
    if($t =~ /\B[A-Z]/) { print "true ($&)\n" } else { print "false\n" }  # Test 2

Im Test 1 wird nach dem ersten Großbuchstaben an einer Wortgrenze gesucht; hier wird das 'D' ('Der ASCII-Code') gefunden, auch wenn es hier nicht (am Anfang des Strings) nach einem Zeichen aus `\W` steht, da Anfang und Ende eine entsprechende Sonderbehandlung erfahren. Test 2 dagegen sucht nach einem Großbuchstaben innerhalb eines Wortes; die Lösung lautet hier 'S' ('Der ASCII-Code').

Autor: Eike Grote | Letzte Änderung: 03.11.2004