Im Abschnitt zur Mehrfachsuche wirkte eine entsprechende Anweisung immer
nur auf das eine unmittelbar davor stehende Zeichen. Mit Hilfe von
Klammern ("(...)
") können auch längere Ausdrücke
mehrfach gesucht werden.
Dazu ein Beispiel:
#!/usr/local/bin/perl -w $t = "1.030303"; if($t =~ /03{2,3}/) { print "true ($&)\n" } else { print "false\n" } # Test 1 if($t =~ /(03){2,3}/) { print "true ($&)\n" } else { print "false\n" } # Test 2 |
false
" (es wird nach einer
'0' gefolgt von 2 oder 3 '3'en gesucht). Erfolgreich
dagegen verläuft
Klammern bewirken auch noch einen Nebeneffekt: Derjenige Substring, der auf
das Muster der ersten Klammer paßt, wird in die Variable $1
geschrieben, der zweite Substring in $2
, usw. Zur Festlegung der
Reihenfolge der Klammern zählt die jeweils öffnende Klammer (dies
ist wichtig bei ineinander verschachtelten Klammerpaaren).
#!/usr/local/bin/perl -w $t = "Breite: 7.5 m"; if($t =~ /(\w+): ([\d.]+ m)/) { print "true ($&)\n" } else { print "false\n" } print "\$1: $1\n"; print "\$2: $2\n"; |
Auch dieser recht kompliziert aussehende reguläre Ausdruck läßt sich relativ einfach auflösen:
(\w+)
sucht nach mindestens einem alphanumerischen Zeichen
und schreibt ggf. den gefundenen Substring in die Variable $1
.
([\d.]+ m)
sucht nach mindestens einem Zeichen aus der
Gruppe "Ziffern und Punkt" gefolgt von einem Leerzeichen und dem
Buchstaben 'm'; das Ergebnis landet ggf. in $2
.
$1
den Wert 'Breite'
und $2
den Wert '7.5 m'. Da alle Bedingungen der
Suche erfüllt sind, ergibt sich natürlich der Gesamtwert "true
".
Möchte man den Nebeneffekt der Zuweisung von $1
, $2
,
$3
,... verhindern, fügt man nach der öffnenden Klammer
"?:
" ein.
#!/usr/local/bin/perl -w $t = "a b"; $t =~ /(.)\s(.)/; print "\$1: $1\n"; # gibt 'a' aus $t =~ /(?:.)\s(.)/; print "\$1: $1\n"; # gibt 'b' aus |
Im ersten Test werden sowohl $1
(mit 'a') als auch
$2
(mit 'b') belegt. Im zweiten Test dagegen findet
bei der ersten Klammer keine Zuweisung statt und der Inhalt der zweiten
Klammer ('b') wird in $1
geschrieben.
Es ist sogar möglich, schon innerhalb des regulären Ausdrucks auf
vorher im String gefundene Teilstrings zuzugreifen. So findet sich der
Wert der ersten Klammer in \1
, der der zweiten Klammer in
\2
, usw. Die Zuordnung ist identisch zu der von $1
,
$2
, usw., allerdings dürfen die 'Backslash-Variablen' nur
innerhalb des Suchmusters und die 'Dollar-Variablen' nur außerhalb
verwendet werden.
#!/usr/local/bin/perl -w $t = "abc--defg-h----ijk"; if($t =~ /(.{2}).+?\1/) { print "true ($&)\n" } else { print "false\n" } print "\$1: $1\n"; |
Der reguläre Ausdruck sucht nach genau zwei gleichen Zeichen, die aber
ansonsten beliebig gewählt sein können, gefolgt von einer möglichst
kurzen Zeichenkette aus mindestens einem Symbol gefolgt von dem Zeichenpaar,
das in der ersten Klammer gefunden wurde. Der gefundene Substring lautet
dann '--defg-h--' und $1
enthält wie erwartet
'--'.
Die Verwendung von \1
, \2
, usw. kann zu Problemen
führen, wenn sich daran eine Suche nach Ziffern anschließt; eine
mögliche Lösung ist die Benutzung von Klammern des Typs
"(?:...)
":
#!/usr/local/bin/perl -w $t = "12--456--12"; if($t =~ /(--)\d+?\112/) { print "true ($&)\n" } # Test 1 else { print "false\n" } if($t =~ /(--)\d+?(?:\1)12/) { print "true ($&)\n" } # Test 2 else { print "false\n" } |
Hier schlägt \112
als
Oktal-Code interpretiert wird (Zeichen 'J'). Die zusätzliche Klammer
in
Autor: Eike Grote | Letzte Änderung: 02.10.1997 |