/blog/perl


substr() in Perl
[154367 mal gelesen]
foreach in Perl
[129203 mal gelesen]
Arrays in Perl - Besonderheiten
[125502 mal gelesen]
split() in Perl - Zeichenketten teilen
[113718 mal gelesen]
open() - Dateien öffnen in Perl
[109041 mal gelesen]
grep - Listen durchsuchen in Perl
[94792 mal gelesen]
chomp() in Perl
[93668 mal gelesen]
push in Perl
[90892 mal gelesen]
sleep in Perl - Das aktuelle Script warten lassen
[76015 mal gelesen]
index() in Perl - Zeichenkette in Zeichenkette suchen
[59664 mal gelesen]


Arrays
Dateien
HTPC
Hashes
Leistungsoptimiert
PHP
Perl
RegEx
Schleifen
Script
Skalare
Sonstiges
System
Webserver
Zur Startseite


Freitag, 2.2.2007, 11:24:31 Uhr

Reguläre Ausdrücke


Reguläre Ausdrücke sind das wahrscheinlich mächtigste Werkzeug in Perl. Mit diesen regulären Ausdrücken kann man Skalare relativ einfach nach bestimmten Zeichen oder Zeichenketten durchsuchen, man kann aber auch relativ einfach einzelne Zeichen oder Zeichenketten austauschen, löschen oder einfügen.
Wie sie vielleicht merken, sage ich immer relativ einfach. In Wahrheit braucht es einiges an Zeit und Übung, bis man sich an den Syntax gewöhnt hat.

Aber fangen wir einfach mal von vorne an:

Einfache Zeichensuche

Wir fangen mit dem einfachsten Beispiel an, der Suche nach EINEM BESTIMMTEN Zeichen:


$t = "Test";
if($t =~ /e/) { print "wahr";} else { print "falsch";}



Wie Sie vielleicht schon wissen, ist der reguläre Ausdruck das "~ /e/".
Aber was bedeutet das nun?
Also, das =~ / bedeutet "suche nach", und zwar nach dem, was zwischen den beiden // steht, also dem kleinen e, und auch nur danach.
Da das e in Test vorhanden ist, wird vom Script ein "wahr" ausgegeben. Ein "falsch" wäre ausgegeben worden, wenn $t="TEST" gewesen wäre, also das E gross geschrieben.

Diese Schreibweise findet also genau das, und nur das, was zwischen den beiden // steht!
Natürlich könnte man zwischen die beiden // noch andere Sachen setzen, beliebig viele Buchstaben oder Ziffern oder Sonderzeichen.


$t="Der Maurer mauert Mauern";
if($t =~ /rer/) { print "wahr\n" } else { print "falsch\n" } # Test 1
if($t =~ /mauert Mauern/) { print "wahr\n" } else { print "falsch\n" } # Test 2
if($t =~ /der maurer/) { print "wahr\n" } else { print "falsch\n" } # Test 3



Dieses Skript liefert nur in den ersten beiden Tests "wahr", im dritten Test ein falsch, da der maurer ja klein geschrieben (also falsch) ist.

So weit, so einfach, so gut!

Aber jetzt gehts schon los mit den Besonderheiten:
Einige Zeichen können nicht ohne weiteres verwendet werden, da sie von den regulären Ausdrücken selbst verwendet werden, nämlich als Steuerzeichen. Gesehen hat man das ja schon an dem /-Zeichen.

Die Zeichen, die nicht einfach so verwendet werden dürfen, sind die Zeichen

. ? * + ^ $ | \ / ( ) [ ] { } ; #

sowie jeweils das Zeichen, das als "Klammer" um den regulären Ausdruck verwendet wird (im Allgemeinen meistens der Schrägstrich "/").
Will man nach diesen Zeichen suchen, so muß man einen Backslash ("\") voranstellen, wie in folgendem Beispiel:


$t="Reguläre Ausdrücke können auch kompliziert sein...";
if( $t=~ /\.\.\./){ print "wahr\n" } else { print "falsch\n" } # Test 1
if($t=~ /\./) { print "wahr\n" } else { print "falsch\n" } # Test 2
if($t=~ /./) { print "wahr\n" } else { print "falsch\n" } # Test 3



Diese Tests liefern alle "wahr".
Test 1 findet tatsächlich die drei Punkte am Ende. Test 2 findet den ersten der drei Punkte, Test 3 findet das R am Anfang.

Für einige häufig gebrauchte Zeichen, die sich schlecht direkt darstellen lassen, gibt es besondere Symbole (siehe auch unter Stringkonstanten):

\n neue Zeile
\r Wagenrücklauf
\f Seitenvorschub
\t Tabulator
\a Signalton
\e Escape

Übrigens lassen sich alle Zeichen auch als Oktal-Code angeben. Schreiben Sie dazu den ASCII-Code in Oktal mit einem Backslash davor, also zum Beispiel \101 für das "A".
Achtung: Es müssen immer drei Stellen sein, auch wenn sie nicht erforderlich zu sein scheinen, wie zum Beispiel bei 005!

Ich möchte an dieser Stelle nochmals auf die ganz besondere Bedeutung des Punktes . eingehen.
Der . kann jedes beliebige Zeichen darstellen, einzige Ausnahme ist der Zeilenvorschub \n.
Diese Fähigkeit macht den . sehr wichtig für reguläre Ausdrücke.


$t="Der Punkt als Universalzeichen";
if($t =~ /P...t/) { print "wahr\n" } else { print "falsch\n" } # Test 1



Ergibt ein wahr, da im Wort Punkt zwischen P und t drei beliebige Zeichen stehen. Gefunden werden würde auch "Paket" oder "Puket", nicht aber "Pakt" (nur zwei Zeichen) zwischen P und t, oder "punkt" (Kleinschrift!).
Wie wir später sehen werden kann der Punkt sehr hilfreich sein, wenn es um das Ersetzen von Zeichen geht.

Was fällt mir dazu noch ein?

Yo, folgendes:

Das Suchen kann auch folgendermaßen durchgeführt werden:

$t="Noch eine Suchart";
$s="eine";
if ($t=~/$s/){print "wahr";} else {print "falsch";}



Das, was gesucht wird, steht also selbst in einem Skalar. Das hat natürlich den Vorteil, daß man nicht jedesmal ein RegEx für jede Suche schreiben muß.

$t="Noch eine Suchart";
$s=".";
if ($t=~/$s/){print "wahr";} else {print "falsch";}


Ausgabe: wahr

Der . in $s findet das "N" am Anfang.

So und jetzt was zur allgemeinen Verwirrung:

#Beispiel 1
$t="Noch eine Suchart";
$s="\.";
if ($t=~/$s/){print "wahr";} else {print "falsch";}


Man könnte meinen, daß jetzt nach dem richtige, echten, einzig wahren . gesucht wird, aber falsch gedacht, gefunden wird wieder das "N".

Erst mal der Beweis dafür: (ich muß da allerdings etwas vorgreifen auf Sachen, die ich noch nicht erklärt habe)

$t="Noch eine Suchart";
$s="\.";
if ($t=~ /($s)/){print "wahr, gefunden wurde $1";} else {print "falsch";}



Wieso? Also, $s="\." bedeutet für Perl: Verarbeite das, was zwischen den beiden " steht und weise es $s zu.
In diesem Fall bedeutet das: \. ist der Punkt, und dieser Punkt wird $s zugewiesen!
Also ist $s="\." equivalent zu $s="."

Beweis:

$t="Noch eine Suchart";
$s="\.";
if ($t=~ /($s)/){print "wahr, gefunden wurde $1\n";} else {print "falsch\n";}

#hier wird $s genauer untersucht
print "Inhalt von \$s: $s \nLaenge von \$s: ".length($s)." Zeichen";



Ausgabe unten: Laenge von $s=1, Inhalt = .

Jetzt wird auch klar, warum das Beispiel oben (Beispiel1) das N gefunden wird!

Ja, kann man sagen, das ist ja schön, aber wenn ich nun wirklich nur den Punkt, und nur den(!) finden will?
Dann kann man den Punkt folgendermaßen codieren:


$t="Noch eine Suchart";
$s='\.';
if ($t=~ /($s)/){print "wahr, gefunden wurde $1\n";} else {print "falsch\n";}

#hier wird $s genauer untersucht
print "Inhalt von \$s: $s \nLaenge von \$s: ".length($s)." Zeichen";



Ausgabe: falsch
laenge von $s: 2, Inhalt = \.

Wenn man also den Punkt als solchen suchen möchte, muß man die zu suchende Zeichenkette nicht zwischen "-Zeichen schreiben, sondern zwischen '-Zeichen!

Erklärung:
Zeichen zwischen '-Zeichen werden nicht evaluiert, sie werden also so übernommen, wie sie eingegeben werden!



So, das war's erstmal mit dem "einfachen" Suchen.

Weiter mit den Regulären Ausdrücken geht's demnächst hier.



Kommentare zum Beitrag "Reguläre Ausdrücke"

Kommentar von Hank

Ein Supertool zum Testen ist RegExr: http://schraegschrift.de/ online-regulaere- ausdruecke-testen/



Thema: Perl RegEx

Der Beitrag "Reguläre Ausdrücke" wurde 7565 mal gelesen.

Kommentar schreiben  Druckansicht  Seitenanfang 
Beurteilen 






 Zufällige Beiträge im /blog/perl

Zeitkontrolle eines Scriptes - times() in Perl

Windows 7 XP Mode – Wo finde ich den XP-Modus unter Windows 7?

substr() in Perl

Leitrechner steht auf 0

time - Zeit in Sekunden in Perl

index() in Perl - Zeichenkette in Zeichenkette suchen

Continue in Perl - Erweiterte Schleifenausführung

Umgebungsvariablen in Perl



0.0268208980560303 sec. to build



...Blogsoftware in pure Perl - Powered by a lot of Coffee...


SSD-Festplatte - Wassn das???
Die Transliteration - Nur ein Zeichen in einem Skalar ersetzen
Select - Case in Perl
Windows 7 XP Mode – Wo finde ich den XP-Modus unter Windows 7?
Mac-Adresse beim Apple Macintosh herausfinden
SGN-Funktion für Perl

Eigene IP herausfinden mit Perl
Epoche live in Datum umwandeln
Firefox 3 - Exe-Files downloaden


Gesamtverzeichnis
Februar 2010
Dezember 2009
Oktober 2009
Januar 2009
Dezember 2008
November 2008
September 2008
August 2008
Juli 2008
Juni 2008
Mai 2008
April 2008
Januar 2008
Dezember 2007
November 2007
Oktober 2007
September 2007
August 2007
Juni 2007
Mai 2007
April 2007
März 2007
Februar 2007
Januar 2007
Dezember 2006


Mister Wong

RSS-Feed

Heute ist der
26.12.2024

Es ist
13:54:26 Uhr

Ihre IP:
18.225.56.181

Blog-Einträge: 186

Die letzten 24 Stunden im Überblick


Gelesene Beiträge insgesamt:
4428248


Webseiten vergleichen
Kalender mit Feiertagen - 2028
Links finden und testen
Menschliche Datumsangaben
IP zu Domain herausfinden
Time live in Datum umwandeln
Perl für Windows



Impressum