Galileo Computing <openbook>
Galileo Computing - Programming the Net
Galileo Computing - Programming the Net


JavaScript von Christian Wenz
Browserübergreifende Lösungen
JavaScript - Zum Katalog
gp Kapitel 12 Formulare II
  gp 12.1 Daten behalten
  gp 12.2 Dynamische Auswahllisten
  gp 12.3 Überprüfungsfunktionen
  gp 12.4 Reguläre Ausdrücke
  gp 12.5 Fragen & Aufgaben

Kapitel 12 Formulare II

Der Bürokrat tut seine Pflicht
von neun bis eins,
Mehr tut er nicht
– Carl Zeller

Im Kapitel »Formulare I« haben Sie gelernt, wie man mit JavaScript allgemein auf Formulardaten zugreifen kann. In diesem Kapitel werden einige fortgeschrittenere Techniken dargestellt, wie man Formulare sinnvoll nutzen kann. Neben neuen Möglichkeiten der Formularüberprüfung mit Browsern der Version 4 erfahren Sie hier auch einige Tricks und Kniffe, die in der täglichen Praxis von Nutzen sein können. Spätestens hier sind die Möglichkeiten von JavaScript 1.0 oft begrenzt, was Sie immer im Hinterkopf behalten sollten.


Galileo Computing

12.1 Daten behalten  downtop

Im vorangegangenen Kapitel haben Sie gesehen, wie man Daten in Cookies speichern kann und somit beispielsweise einen JavaScript-Warenkorb ohne Frames realisieren kann. Der Nachteil wurde auch nicht verschwiegen: Während die meisten Benutzer JavaScript nicht deaktivieren, schalten viele User die Verwendung von Cookies aus, natürlich auch bedingt durch Horrormeldungen in der Presse. Es gibt jedoch auch Möglichkeiten, ohne Cookies Daten von einer HTML-Seite zur nächsten zu übernehmen. Eine der Alternativen besteht in der Verwendung von Frames und der Datenspeicherung in einem davon; hier sei auf Kapitel »Fenster II« verwiesen. In diesem Abschnitt wird eine weitere Möglichkeit vorgestellt.

Ein virtueller Geschäftsmann will den Besuchern seiner Website Bücher in elektronischer Form zum Download anbieten. Er hat eine ganze Reihe davon, und so soll der Benutzer in einem Formular die für ihn interessanten Programme auswählen können. Nach Absenden des Formulars erhält er Links auf die ausgewählten Programme. Bevor Sie das Beispiel eins zu eins kopieren, sollten Sie allerdings die Copyright-Fragen klären.


Galileo Computing

12.1.1 Das Eingabeformular  downtop

Das Formular selbst ist schnell erstellt; als zusätzlicher Bonus werden dem Benutzer zu jedem Programm Hintergrundinformationen zu jedem Produkt in einem neuen Fenster angezeigt. Wie das prinzipiell funktioniert, wurde schon im Kapitel »Fenster III« gezeigt. Beachten Sie im folgenden, dass jeder Checkbox konsistent das VALUE-Attribut "on" zugewiesen worden ist. Der Sinn dieser Maßnahme wird weiter unten klar.

Abbildung 12.1  Das HTML-Formular
Abbildung

<HTML>
<HEAD>
<TITLE>Bücher-Download</TITLE>
<SCRIPT LANGUAGE="JavaScript"><!--
function hilfe(seite){
   window.open(seite, "hilfefenster","height=300,width=400")
}
//--></SCRIPT>
</HEAD>
<BODY>
<H3>Wählen Sie hier Ihre Bücher aus!</H3>
<FORM METHOD="GET" ACTION="download.html">
<INPUT TYPE="CHECKBOX" NAME="sommer" VALUE="on">
 <A HREF="javascript:hilfe('sommer.html')">Sommernachtstraum</A><BR>
<INPUT TYPE="CHECKBOX" NAME="othello" VALUE="on">
 <A HREF="javascript:hilfe('othello.html')">Othello<</A>BR>
<INPUT TYPE="CHECKBOX" NAME="venedig" VALUE="on">
 <A HREF="javascript:hilfe('venedig.html')">Der Kaufmann von
   Venedig</A><BR>
...<BR>
<INPUT TYPE="SUBMIT" VALUE="Zum Download">
</FORM>
</BODY>
</HTML>

Galileo Computing

12.1.2 Die Ausgabeseite  downtop

Wenn Sie das Formular auf der vorherigen Seite genauer betrachtet haben, wird Ihnen folgende Zeile nicht entgangen sein:

<FORM METHOD="GET" ACTION="download.html">

Zum einen ist das ACTION-Attribut unüblich – seit wann übergibt man Formularwerte an eine HTML-Seite? Zum anderen ist METHOD auf "GET" gesetzt. Dazu ein kleiner Exkurs: Mit METHOD wird die Versendemethode des Formulars angegeben. Standardmäßig, also auch, wenn nichts angegeben wird, wird die Methode POST verwendet. In diesem Fall werden die Formulareingaben als eigener Teil des HTTP-Headers bei der Anforderung der Zielseite versandt. Die entsprechende HTTP-Anforderung des Webbrowsers an den Webserver sieht ungefähr folgendermaßen aus:

POST /download.html HTTP/1.1
Content-type: application/x-www-form-urlencoded
Accept: text/plain
Content-length: 21

othello=on&venedig=on

Sie sehen, dass die einzelnen (angekreuzten) Checkboxen im Formular NAME=VALUE übergeben und voneinander mit dem kaufmännischen Und (&) getrennt werden.

Wenn wie im obigen Beispiel die Methode GET verwendet wird, sieht die Sache anders aus: Hier werden nämlich die Formulardaten als Teil der URL übergeben, es würde folgende Seite aufgerufen werden:

download.html?othello=on&venedig=on

Diese Daten kann man mit JavaScript abfragen. Wie Sie sich vielleicht erinnern, erhält man mit location.search den Teil der URL ab dem Fragezeichen, in diesem Fall also ?othello=on&venedig=on. Mit JavaScript können diese Daten zerlegt werden, um die Ausgabeseite zu generieren.

Um die ganze Sache ein wenig zu vereinfachen, gehen wir davon aus, dass alle Bücher im Verzeichnis download liegen, die Dateiendung .zip haben und sich der Teil vor der Endung aus dem NAME-Attribut der zugehörigen Checkbox ergibt. Der Programmierer muss also nur noch folgende Aufgaben erledigen:

gp  Er muss die Eigenschaft location.search auslesen und das erste Zeichen (das Fragezeichen) abschneiden.
gp  Er muss die übrigbleibende Zeichenkette an den kaufmännischen Unds aufteilen. Die einzelnen Teile haben dann den Aufbau buchname=on, und wenn man das =on entfernt, hat man den Dateinamen ohne die Endung.

Man kann den Algorithmus ein wenig vereinfachen, indem man einfach nach dem nächsten Vorkommen von & sucht, außerdem nach dem nächsten Vorkommen von =on und dann die Zeichenkette dazwischen betrachtet. Die Zeichenkette =on kann übrigens an keiner anderen Stelle (also zum Beispiel links vom Gleichheitszeichen) in der URL erscheinen. Der Grund dafür ist, dass Sonderzeichen in ein URL-konformes, hexadezimales Format umgewandelt werden. Aus einem Leerzeichen wird %20, und aus einem Gleichheitszeichen wird %3D. 3D ist nämlich die hexadezimale Darstellung der Dezimalzahl 62, und im ASCII-Zeichensatz hat das Gleichheitszeichen den Code 62. Der ASCII-Code des Leerzeichens ist 32, und die hexadezimale Darstellung ist 20. Die Umwandlung in dieses URL-Format geschieht automatisch; die Rückverwandlung erfolgt mit der JavaScript-Funktion unescape(). So liefert beispielsweise unescape("%3D") das Ergebnis "=" zurück. Die Umwandlung ist im übrigen auch mit JavaScript möglich, escape("=") liefert "%3D".

Der Internet Explorer 5.5 bietet hierzu übrigens ein paar neue Funktionen an, die eine URI (Unified Ressource Identificator, eine Art Obermenge von URL) erzeugen können. Die Funktion encodeURI() wandelt den übergebenen Parameter in eine URL um, also liefert beispielsweise encodeURI (»meine Webseite.html#oben«) als Ergebnis meine%20Webseite.html#oben zurück. Sie sehen hier, dass das Doppelkreuz als Abtrennungszeichen für einen HTML-Anker interpretiert worden ist, also insbesondere nicht in die hexadezimale Form %23 umgewandelt wurde. Wenn Sie auch das möchten (beispielsweise, wenn Sie die obige URL als Parameter an ein CGI-Skript übergeben möchten), müssen Sie encodeURIComponent() verwenden. Dies liefert das gewünschte Ergebnis, encodeURIComponent(»meine Webseite.html#oben«) gibt meine%20Webseite.html%23oben zurück.

Die entsprechenden Funktionen, die eine kodierte URL wieder entschlüsseln, heißen decodeURI() und decodeURIComponent(). Und wie erwartet gibt decodeURI(»meine%20Webseite.html#oben«) als Ergebnis meineWebseite.html#oben zurück, decodeURIComponent(»meine%20 Webseite.html %23oben«) liefert ebenfalls meine Webseite.html#oben.

Aus den vielzitierten Gründen der Abwärtskompatibilität müssen Sie jedoch noch eine ganze Weile auf den Einsatz dieser Funktionen verzichten, wenn Sie möglichst viele Browser unterstützen wollen.

Zurück zur Aufgabenstellung: Der folgende Code (zu speichern als download.html) liest die übergebenen Daten aus und generiert die Ausgabeseite.

<HTML>
<HEAD>
<TITLE>Download Seite 2</TITLE>
<SCRIPT LANGUAGE="JavaScript"><!--
function tag(s){ return("<"+s+">") }
function ausgabe(){
   var ls = location.search
   var txt = (ls.length>1) ? "Sie können die Bücher nun
     herunterladen" : "Keine Bücher ausgewählt"
   document.write(txt + tag("BR"))
   if (ls.length<=1)  //Funktion verlassen, falls
                      //nichts ausgewählt wurde
      return false
   ls = "&" + ls.substring(1, ls.length)
      //Fragezeichen entfernen, "&" vorne anhängen
   var pos = 0 //aktuelle Suchposition in location.search
   while (pos==0||ls.indexOf("&", pos) != -1){
      start = ls.indexOf("&", pos)+1
      ende = ls.indexOf("=on", pos)
      buch = unescape(ls.substring(start, ende))
      document.write(tag("A HREF='download/"+buch+".zip'"))
      document.write(buch)
      document.write(tag("/A")+tag("BR"))
      pos = ende + 2
   }
}
//--></SCRIPT>
</HEAD>
<BODY>
<H3>Bücher-Download</H3>
<SCRIPT LANGUAGE="JavaScript"><!--
ausgabe()
//--></SCRIPT>
<NOSCRIPT>
Ihr Browser unterstützt kein JavaScript!
</NOSCRIPT>
</BODY>
</HTML>
Abbildung 12.2  Die Download-Seite
Abbildung


Galileo Computing

12.2 Dynamische Auswahllisten  downtop

Erinnern Sie sich noch an die Navigation aus dem Kapitel »Images«? Dort gab es mehrere Kategorien, die aufgrund einer Mausbewegung ausklappen und Unterpunkte freigeben. Dies lässt sich sehr platzsparend auch in einem Formular realisieren. Es ist insbesondere möglich, via JavaScript einzelne Punkte in den Auswahllisten zu ändern, zu löschen und neue Punkte hinzuzufügen. Allerdings muss der Browser die JavaScript-Version 1.1 unterstützen. Sie müssen also den Netscape Navigator ab Version 3 bzw. den Internet Explorer ab Version 4 benutzen.


Galileo Computing

12.2.1 Ein erster Ansatz  downtop

Wie Sie wissen, werden die einzelnen Optionen einer Auswahlliste im Array options[] gespeichert. Jede einzelne dieser Optionen hat die Eigenschaft text, die den im Browser angezeigten Text angibt. Wie gesagt, diese Eigenschaft kann erst ab JavaScript 1.1 modifiziert werden.

Das ist an sich kein Problem, aber nicht alle Kategorien haben die gleiche Anzahl von Unterpunkten. Da jedoch die einzelnen Optionen in einem Array gespeichert werden, liegt es nahe, die Eigenschaft length dieses Arrays zu ändern. Ein erster Ansatz für die Navigation finden Sie im nachfolgenden Listing. Die linke Auswahlliste enthält die Kategorien, und wenn eine davon ausgewählt wird (Event-Handler: onChange), werden die Untermenüpunkte in der rechten Auswahlliste angezeigt. Sobald dort ein Punkt ausgewählt wird, kann die entsprechende Webseite geladen werden. Wie im Beispiel aus dem Kapitel »Images«, stehen die wichtigen Variablen – in diesem Falle die URLs und die Namen der einzelnen Menüpunkte – am Anfang des Skripts in globalen Variablen, damit sie einfach angepasst werden können.

<HTML>
<HEAD>
<TITLE>Navigation mit Auswahllisten – Teil 1</TITLE>
<SCRIPT LANGUAGE="JavaScript"><!--
function kategorie_anzeigen(){}
function seite_laden(){}
//--></SCRIPT>
<SCRIPT LANGUAGE="JavaScript1.1"><!--
// *** globale Variablen
var urls = new Array(
   new Array(""),
   new Array("", "seite1-1.html", "seite1-2.html", "seite1-3.html"),
   new Array("", "seite2-1.html", "seite2-2.html"),
   new Array("", "seite3-1.html", "seite3-2.html", "seite3-3.html",
 "seite3-4.html")
)
var beschriftung = new Array(
   new Array("Bitte auswählen", ""),
   new Array("Bitte auswählen", "Punkt 1.1", "Punkt 1.2",
     "Punkt 1.3"),
   new Array("Bitte auswählen", "Punkt 2.1", "Punkt 2.2"),
   new Array("Bitte auswählen", "Punkt 3.1", "Punkt 3.2",
     "Punkt 3.3", "Punkt 3.4")
)
// *** Ende der globalen Variablen
function kategorie_anzeigen(f){
   var kategorie = f.kategorien.selectedIndex
   f.unterpunkte.options.length=urls[kategorie].length
   for (var i=0; i<urls[kategorie].length; i++)
      f.unterpunkte.options[i].text = (beschriftung[kategorie])[i]
}
function seite_laden(f){
   var kategorie = f.kategorien.selectedIndex
   var unterpunkt = f.unterpunkte.selectedIndex
}
//--></SCRIPT>
</HEAD>
<BODY>
<H3>Navigation mit Auswahllisten</H3>
<FORM>
<SELECT NAME="kategorien" onChange="kategorie_anzeigen(this.form)">
 <OPTION>Bitte auswählen</OPTION>
 <OPTION>Kategorie 1</OPTION>
 <OPTION>Kategorie 2</OPTION>
 <OPTION>Kategorie 3</OPTION>
</SELECT>
<SELECT NAME="unterpunkte" onChange="seite_laden(this.form)">
 <OPTION>Bitte auswählen</OPTION>
</SELECT>
</FORM>
</BODY>
</HTML>
Abbildung 12.3  Die beiden Auswahllisten
Abbildung

Wenn Sie dieses Beispiel im Browser ausprobieren, werden Sie allerdings wahrscheinlich einen kleinen Nachteil feststellen: Wenn Sie das zweite Auswahlmenü ausklappen wollen, werden Sie – bei manchen Browsern und Betriebssystemen – interessante grafische Nebeneffekte feststellen (siehe Abbildung 12.4). Um diese zu vermeiden, muss das obige Skript etwas sauberer programmiert werden.

Abbildung 12.4  Das Scrollen der rechten Auswahlliste ist schwierig.
Abbildung


Galileo Computing

12.2.2 Ein fortgeschrittener Ansatz  downtop

Um das Beispiel ganz sauber zu programmieren, sollte man zuerst alle Optionen in der Auswahlliste löschen und dann die Optionen hinzufügen. Für Menüoptionen gibt es einen eigenen Konstruktor, new Option("Beschriftung", "VALUE-Attribut").

Eine einzelne Option kann gelöscht werden, indem das entsprechende Element im Array options[] auf null gesetzt wird. Mit folgendem Kommando wird die zweite Option in einer Auswahlliste gelöscht:

document.forms[0].auswahlliste.options[1] = null

Sie können sich den Aufwand jedoch sparen, wenn Sie die Eigenschaft length des Arrays options[] auf 0 setzen. Dann können die Optionen erzeugt werden. Die Eigenschaft length wird hierbei automatisch angepasst. Es genügt, wenn Sie die Funktion kategorie_anzeigen() folgendermaßen abändern:

function kategorie_anzeigen(f){
   var kategorie = f.kategorien.selectedIndex
   f.unterpunkte.options.length=0
   for (var i=0; i<urls[kategorie].length; i++)
      f.unterpunkte.options[i] = 
        new Option((beschriftung[kategorie])[i], "")
}
Abbildung 12.5  Jetzt fällt das Scrollen leichter.
Abbildung

Außerdem hilft es, pro forma in die linke Auswahlliste ein paar freie leere Felder einzufügen; vor allem der Netscape Navigator führt das Skript dann zuverlässiger aus.

Wie Sie sehen, umgehen Sie so grafische Unfälle.


Galileo Computing

12.3 Überprüfungsfunktionen  downtop

Im Kapitel »Formulare I« wurden Formulare auf Vollständigkeit überprüft. In der Praxis gibt es jedoch noch weitere Anforderungen. Manche Eingabefelder verlangen besondere Eingaben, beispielsweise Postleitzahlen, Telefonnummern oder Uhrzeiten. In diesem Abschnitt werden einige Funktionen aus diesem Bereich entwickelt.


Galileo Computing

12.3.1 Ganze Zahlenwerte  downtop

In JavaScript gibt es die Funktion isNaN(), die feststellt, ob ein Eingabewert keine Zahl ist. Der große Nachteil an dieser Funktion ist, dass der Netscape Navigator 2 sie nur in der UNIX-Version unterstützt. Aus diesem Grund muss man sich diese Funktion selbst programmieren. Der Eingabewert wird dazu als Zeichenkette betrachtet, und bei jedem Zeichen wird überprüft, ob es eine Ziffer von 0 bis 9 ist. Sollte das für alle Zeichen zutreffen, handelt es sich um eine Zahl, ansonsten liegt keine Zahl vor.

function isANumber(n){
   var s = "" + n //Umwandlung in eine Zeichenkette
   var ziffern = "0123456789" //Gültige Zeichen
   for (var i=0; i<s.length; i++)
      if (ziffern.indexOf(s.charAt(i))==-1) //keine Ziffer
         return false
   return true
}

Mit dieser Methode kann man beispielsweise überprüfen, ob ein Eingabewert eine deutsche Postleitzahl darstellen könnte:

if (eingabe.length==5 && isANumber(eingabe))

Strenggenommen sind aber nicht alle Postleitzahlen natürliche Zahlen, so beispielsweise 01234. Das ist die Postleitzahl einiger Postfächer in Dresden, aber keine natürliche Zahl, da sie mit 0 beginnt, was nicht sein darf (Ausnahme: die Null selbst). Für streng nummerische Eingaben (beispielsweise ein Anzahl-Feld in einem Bestellformular) muss man die Funktion folgendermaßen umschreiben:

function isANumber2(n){
   var s = "" + n //Umwandlung in eine Zeichenkette
   var ziffern = "0123456789" //Gültige Zeichen
   if (s=="0") //Bei "0"
      return true
   if (s.charAt(0)=="0") //Bei 0 am Anfang
      return false
   for (var i=0; i<s.length; i++)
      if (ziffern.indexOf(s.charAt(i))==-1) //keine Ziffer
         return false
   return true
}

Im dritten Schritt soll noch die zusätzliche Funktionalität implementiert werden, dass auch negative Zahlen erkannt werden, beispielsweise »-42«. Die Überprüfung gestaltet sich jedoch sehr einfach. Ist das erste Zeichen ein Minus, wird es einfach abgetrennt. Hinter dem Minuszeichen dürfen nur noch Ziffern stehen, also bleibt alles wie gehabt.

function isANumber3(n){
   var s = "" + n //Umwandlung in eine Zeichenkette
   var ziffern = "0123456789" //Gültige Zeichen
   if (s.charAt(0)=="-")  //führendes Minus entfernen
      s = s.substring(1, s.length)
   if (s=="0") //Bei "0"
      return true
   if (s.charAt(0)=="0") //Bei 0 am Anfang
      return false
   for (var i=0; i<s.length; i++)
      if (ziffern.indexOf(s.charAt(i))==-1) //keine Ziffer
         return false
   return true
}

Galileo Computing

12.3.2 Dezimalzahlen  downtop

Das Überprüfen von Dezimalzahlen ist schon eine etwas anspruchsvollere Aufgabe. Zum einen gibt es den Unterschied zwischen der deutschen und der amerikanischen Schreibweise: Während man in Deutschland den Ganzzahlanteil vom Dezimalteil durch ein Komma trennt, verwendet man in Amerika einen Punkt. JavaScript benötigt für Rechnungen die amerikanische Notation, sodass als aller erstes in einer Überprüfungsfunktion alle Kommata durch Punkte ersetzt werden. Zum anderen darf in der vermeintlichen Dezimalzahl maximal ein Punkt (bzw. Komma) vorkommen.

function isAFract(n){
   var s = "" + n //Umwandlung in String
   while (s.indexOf(",")>-1){//Kommata durch Punkte ersetzen
      s=s.substring(0,s.indexOf(",")) + "." 
+ s.substring(s.indexOf(",")+1 ,s.length)
   }
   var anzahl_punkt=0//Variable zum Zählen der Dezimalpunkte
   for (var i=0; i<s.length; i++)
      if (s.charAt(i)==".")
         anzahl_punkt++
   if (anzahl_punkt>1) //Mehr als ein Dezimalpunkt?
      return false
   // *** Eigentliche Überprüfung nach obigem Muster
   // *** Neu: Der Dezimalpunkt ist ein erlaubtes Zeichen
   var ziffern = ".0123456789" //Gültige Zeichen
   if (s.charAt(0)=="-")  //Führendes Minus entfernen
      s = s.substring(1, s.length)
   if (s=="0") //Bei "0"
      return true
   if (s.charAt(0)=="0" &&s.charAt(1)!=".")
      //Bei 0 am Anfang ohne folgenden Punkt
      return false
   for (var i=0; i<s.length; i++)
      if (ziffern.indexOf(s.charAt(i))==-1) //Keine Ziffer
         return false
   return true
}

Galileo Computing

12.3.3 Telefonnummern  downtop

Es gibt viele Möglichkeiten, eine Telefonnummer zu schreiben. Eine Telefonnummer mit der Vorwahl 0123 und der Rufnummer 456789 kann beispielsweise folgendermaßen geschrieben werden:

gp  (0123) 456789
gp  (01 23) 45 67-89
gp  01234/456789
gp  +49[0]123-456789

Zwar können Sie für jeden dieser Fälle eine eigene Überprüfungsfunktion schreiben, aber in diesem Falle ist es effizienter, einfach eine Liste der wahrscheinlich vorkommenden Zeichen zu erstellen und darauf zu überprüfen. Eine mögliche Validierungsfunktion kann dann so aussehen:

function isAPhoneNumber(n){
   var s = "" + n //Umwandlung in eine Zeichenkette
   var zeichen = "0123456789+-()[]/ " //Gültige Zeichen
   for (var i=0; i<s.length; i++)
      if (zeichen.indexOf(s.charAt(i))==-1)
         //kein gültiges Zeichen
         return false
   return true
}

Galileo Computing

12.3.4 In Zahlenwerte umwandeln  downtop

Wenn man mit Formularen rechnet, ist es oft nicht nur wichtig, Formulareingaben auf nummerische Werte zu überprüfen, sondern auch, diese nummerischen Werte zu erhalten. Zwar gibt es die Funktionen parseFloat("Zeichenkette") für Dezimalzahlen und parseInt("Zeichenkette") für ganze Zahlen, aber diese liefern gegebenenfalls ein NaN-Objekt zurück: Not A Number. Zur Überprüfung des Rückgabewerts von parseFloat() und parseInt() würde man die Funktion isNaN() benötigen, und diese hat ja die eingangs erläuterten Nachteile. Außerdem funktioniert parseFloat() nur mit amerikanisch formatierten Eingabewerten, also mit einem Dezimalpunkt statt einem Dezimalkomma. Im Folgenden soll eine neue Funktion programmiert werden, die der Funktion eval() ähnelt, und einen Eingabewert überprüft und einen nummerischen Wert zurückgibt. Ist der Eingabewert kein korrekt formatierter Zahlenwert, so wird 0 zurückgegeben. Das hat den Vorteil, dass mit Formularen sehr bequem gerechnet werden kann, da hier oft multipliziert wird (etwa Stückzahl mal Preis). Ist ein Eingabewert eine leere Zeichenkette oder allgemein keine Zahl, so wird 0 zurückgegeben, und das Ergebnis der Multiplikation ist auch 0.

Die im Folgenden aufgeführte Funktion benutzt eine bereits zuvor entwickelte Funktion, sodass Sie auf eine konsistente Namensgebung achten müssen.

function smartEval(n){
   var s = "" + n //Umwandlung in eine Zeichenkette
   for (var i=0; i<s.length; i++)  //Kommata in Zahlen
      if (s.charAt(i)==",")
         s=s.substring(0,i)+"."+s.substring(i+1,s.length)
   if (isAFrac(s))
      return 1*s //Umwandlung in einen Zahlenwert
   else
      return 0
}

Galileo Computing

12.4 Reguläre Ausdrücke  downtop

Die Programmiersprache Perl ist unter anderem deswegen so beliebt, weil die Verwendung von regulären Ausdrücken so hoffähig gemacht worden ist. Ein regulärer Ausdruck ist – stark vereinfacht gesagt – eine Zeichenfolge, die ein Textmuster repräsentiert. Dieses Textmuster kann dann in einer längeren Zeichenkette gesucht werden. Ein umgangssprachlich formuliertes Textmuster ist etwa: »ein Wort, das mit J beginnt und zwei ›a‹s enthält«. Auf dieses Textmuster würden beispielsweise sowohl »Java« als auch »JavaScript« passen. Mit regulären Ausrücken kann man beispielsweise Formulareingaben sehr schnell überprüfen. Einige der Funktionen aus dem vorangegangenen Abschnitt können so viel einfacher programmiert werden. Ein Wort zur Warnung aber gleich vorweg: Mit den Methoden des String-Objekts, beispielsweise indexOf() und substring() kann man praktisch alle Funktionalitäten nachbilden, die reguläre Ausdrücke anbieten. Dazu ist jedoch eine Menge Programmierarbeit nötig (es gibt in der Tat auch Programme, die reguläre Ausdrücke in Programmcode umwandeln). Seitdem es die Browser der Generation 4 gibt, kann man sich die Extra-Arbeit sparen. Wenn Sie für ein Intranet arbeiten und wissen, dass nur neue Browser verwendet werden, können Sie reguläre Ausdrücke verwenden. Wenn Ihre Seiten zwar auch von älteren Browsern besucht werden, diese aber klar in der Minderheit sind, können Sie ebenfalls reguläre Ausdrücke verwenden, Sie sollten aber mit einer Abfrage Fehlermeldungen vermeiden.


Galileo Computing

12.4.1 Kurzeinführung  downtop

Ein Muster kann eine einfache Zeichenfolge sein, beispielsweise "abc". Das Interessante an Mustern sind jedoch die Sonderzeichen und Ausdrücke, mit denen man Muster flexibler gestalten kann. Im folgenden werden die wichtigsten dieser Sonderzeichen und Ausdrücke vorgestellt.

Sonderzeichen zum Zählen

Mit diesen Ausdrücken kann angegeben werden, wie oft ein gewisses Zeichen vorkommen darf oder muss. Der Ausdruck muss dabei immer direkt hinter dem Zeichen stehen.

gp  ?: Null- oder einmal. Auf das Muster "ab?c" passen also "ac" und "abc", aber nicht "abbc".
gp  *: Null- oder mehrmals. Auf das Muster "ab*c" passen also "ac", "abc" und "abbc", aber nicht "adc".
gp  +: Ein- oder mehrmals. Auf das Muster "ab+c" passen also "abc" und "abbc", aber nicht "ac".
gp  {n}: Genau n-mal. Auf das Muster "ab{1}c" passt also "abc", aber nicht "abbc". Das Muster ließe sich zu "abc" vereinfachen.
gp  {n.m}: Zwischen n- und m-mal. Auf das Muster "ab{2,3}c" passen also "abbc" und "abbbc", aber nicht "abc".
gp  {n,}: Mindestens n-mal. Das Muster "ab{1,}" ist also äquivalent zu "ab+c". Dieser Ausdruck kann auch vollständig durch vorherige Ausdrücke ersetzt werden; äquivalent zu "ab{5,}c" ist beispielsweise "ab{4}b+c".

Die Sonderzeichen zum Zählen müssen sich nicht nur auf ein einzelnes Zeichen beziehen. Wenn man mehrere Zeichen mit runden Klammern umgibt, werden diese als Gruppe behandelt (die Klammern sind hierbei Sonderzeichen, das Muster sucht also nicht nach den Zeichen "(" und ")"). Auf das Muster "(abc)+" passen also unter anderem "abc", "abcabc" und "abcabcabc".

Metazeichen

Innerhalb eines regulären Ausdrucks versteht man unter einem Metazeichen ein normales Zeichen, das durch einen vorangestellten Backslash (\) eine besondere Bedeutung erhält. JavaScript unterstützt die folgenden Metazeichen:

gp  \b: Wortgrenze. An der Stelle, an der dieses Metazeichen steht, muss ein Wort beginnen oder aufhören, damit das Muster passt. Auf das Muster "\babc" passt beispielsweise "abcde", aber nicht "ababc". Auf "\babc\b" passt nur "abc"; das erste \b steht für den Wortanfang, das zweite für das Wortende.
gp  \B: Keine Wortgrenze, das Gegenteil von \b. Auf das Muster "\Babc" passt beispielsweise "ababc", aber nicht "abcde". Auf das Muster "\Babc\B" passt weder "ababc" (Wortende) noch "abcde" (Wortanfang), aber "babcb".
gp  \d: Ziffer. Auf das Muster "\d\d\d\d" passt beispielsweise "0815", aber nicht "R2D2".
gp  \D: Keine Ziffer. Auf das Muster "\D\D" passt weder "12" noch "A1" noch "1A", aber "AB".
gp  \s: Leerzeichen. Auf das Muster "Java\sScript" passt "Java Script", aber nicht "JavaScript".
gp  \S: Kein Leerzeichen. Auf das Muster "Java\SScript" passen "Java_Script" und "Java-Script", aber nicht "Java Script".
gp  \w: Buchstabe, Ziffer oder Unterstrich (_). Auf das Muster "\w" passen also beispielsweise "A", "a", "1" und "_", aber nicht "!".
gp  \W: Kein Buchstabe oder Ziffer oder Underscore. Auf das Muster "\W" passt beispielsweise "!", aber nicht "A", "a" oder "_".

Weitere Ausdrücke

gp  .: Jedes beliebige Zeichen außer einem Zeilensprung. Auf das Muster ".." passt also jede beliebige Folge zweier Zeichen.
gp  [...]: Eine Auswahlliste von Zeichen. Aus der Liste von Zeichen kann genau eines ausgewählt werden. Die Zeichen stehen dabei hintereinander. Es können auch Abkürzungen vorgenommen werden, beispielsweise bezeichnet "[A-Z]" alle Großbuchstaben und "[0-9]" alle Ziffern. Auf das Muster "[LJ]ava" passt also beispielsweise "Lava" und "Java", aber nicht "Cava". Das Metazeichen "\w" kann durch folgendes Muster ausgedrückt werden: "[a-zA-Z0-9_]" (alle Klein- und Großbuchstaben, Ziffern und Unterstrich).
gp  [^...]: Negierte Auswahlliste. Das Muster "[^a-zA-Z0-9_]" ist also äquivalent zum Metazeichen "\W".
gp  ^: Zeilenanfang. Auf das Muster "^Java" passen beispielsweise "Java" und "JavaScript", aber nicht "I love Java".
gp  $: Zeilenende. Auf das Muster "Java$" passen beispielsweise "I love Java" und "Java", aber nicht "JavaScript".
gp  \: Entwertung eines Sonderzeichens. Das Dollar-Symbol "$" hat in regulären Ausdrücken eine besondere Bedeutung. Will man aber nach dem Währungssymbol suchen, so muss man "$" mit einem vorangestellten Sonderzeichen entwerten. Also passen auf das Muster "\d\d\d \$" beispielsweise "100 $" und "200 $". Natürlich kann ein Backslash auch sich selbst entwerten; auf das Muster "\\" passt "\".
gp  |: Oder-Operation. Auf das Muster "abc|def" passen unter anderem "abc" und "def".

Galileo Computing

12.4.2 Ein Objekt erzeugen  downtop

Ein regulärer Ausdruck kann mit JavaScript auf zwei Arten erstellt werden:

1. var re = new RegExp("ab+c", "gi") Der erste Parameter ist der reguläre Ausdruck, was unschwer zu erkennen ist. Der zweite Parameter ist optional, kann aber – wenn er angegeben wird, einen der Werte "", "g", "i" oder "gi" haben (als regulärer Ausdruck geschrieben: "g?i?"). Hierbei steht "g" für global, und das ist beim Ersetzen wichtig. So kann ein Muster auch mehrmals in einer Zeichenkette gesucht (und gefunden) werden. Für case insensitive, also unabhängig von Groß- und Kleinschreibung, steht "i". Somit ist new RegExp("[a-zA-Z]") äquivalent zu new RegExp("[a-z]", "i").
2. var re = /ab+c/gi Die Bedeutung des "gi" am Ende des Ausdrucks ist die gleiche wie im ersten Punkt. Der Unterschied ist hier, dass der reguläre Ausdruck von Schrägstrichen begrenzt wird. Das sieht im Vergleich zur restlichen JavaScript-Syntax etwas merkwürdig aus, weshalb ich die erste Variante bevorzuge. In diesem Buch wird jedoch die zweite Variante bevorzugt, weil die erste den Nachteil hat, dass z. B. der Backslash innerhalb eines Strings entwertet werden muss, also etwa "\\d". Das macht den Code für den Einsteiger nicht gerade lesbarer. Bei der zweiten Variante ist außerdem zu beachten, dass der Schrägstrich dann ja eine besondere Bedeutung hat und innerhalb des Musters mit einem Backslash entwertet werden muss, damit der JavaScript-Interpreter das Ende des Musters findet. Das Muster "\d\d/\d\d" passt beispielsweise auf "08/15", und new RegExp("\\d\\d/\\d\\d") ist auch korrekt, aber mit der zweiten Schreibweise muss es /\d\d\/\d\d/ heißen.

Galileo Computing

12.4.3 Mit dem Objekt arbeiten  downtop

Auf eine der beiden vorgestellten Arten können Sie ein RegExp-Objekt erzeugen. Dieses Objekt stellt mehrere Methoden zur Verfügung, die Ihnen bei der Anwendung von regulären Ausdrücken von Nutzen sein werden.

Einen Treffer suchen

Man spricht im Englischen von match, einem Treffer, wenn das Muster in der zu durchsuchenden Zeichenkette vorhanden ist. Die dazugehörige Methode lautet test("Zeichenkette"). Das folgende Codestück überprüft, ob es sich bei der Zeichenkette um eine deutsche Postleitzahl handeln könnte:

var re = /\d{5}/
var plz1 = re.test("01234") //gibt true zurück
var plz2 = re.test("8000") //gibt false zurück
var plz2 = re.test("D8000") //gibt false zurück

Mit dem folgenden Code wird überprüft, ob es sich bei dem Eingabewert um eine ganze Zahl handelt. Dieser Test wurde weiter oben schon etwas mühsam entwickelt; hier handelt es sich um deutlich weniger Schreibarbeit:

var re = /0|-?[1-9]\d*/
var zahl1 = re.test("12345") //gibt true zurück
var zahl2 = re.test("01234") //gibt false zurück

Zur Erklärung: Eine ganze Zahl ist entweder die Null oder eine Ziffernfolge, die nicht mit der Null beginnt (also eine Ziffer von 1 bis 9). Hinter der führenden Ziffer stehen beliebig viele weitere Ziffern oder aber auch keine Ziffer mehr. Die Ziffernfolge kann durch ein optionales Minus-Zeichen eingeleitet werden.

Treffer zurückliefern

In der Praxis kommt es oft darauf an, nicht nur einen Treffer zu finden, sondern auch den auf das Muster passenden Teil der Zeichenkette zu erhalten, und teilweise auch darauf, Teile davon zu erhalten.

Oben wurde bereits erwähnt, dass man mit runden Klammern einzelne Zeichen im Muster gruppieren kann. Das ist nicht nur für Nummerierungen von Bedeutung, sondern auch für das Ergebnis, da man den Wert der einzelnen Klammern gezielt abfragen kann. Dies soll an einem Beispiel verdeutlicht werden.

In einem Firmen-Intranet wird die Stundenerfassung elektronisch erledigt. Um Eingabefehler abzufangen, soll JavaScript verwendet werden. Eine Stundenangabe soll im Format »0:30« bzw. »12:45« erfolgen. Der folgende reguläre Ausdruck prüft auf dieses Format. Beachten Sie bitte, dass dabei die ersten runden Klammern um die Stundenzahl stehen, die zweiten runden Klammern um die Minutenzahl.

var dauer = /(1?\d):([0-5]\d)/g

Der gewerkschaftlich organisierte Leser wird gewiss verzeihen, dass Arbeitszeiten bis zu 19 Stunden und 59 Minuten zugelassen werden; der Leser in Führungsposition übersehe, dass keine Arbeitszeiten über 20 Stunden erlaubt sind.

In diesem Beispiel wird die Methode exec("Zeichenkette") des RegExp-Objekts verwendet. Im Gegensatz zu test("Zeichenkette") wird hier nicht einfach ein Boolescher Wert zurückgegeben, sondern ein spezielles Objekt, das den Teil der Zeichenkette enthält, auf die das Muster passt. Außerdem werden auch die Teile innerhalb der runden Klammern abgespeichert. Folgender Code wird das verdeutlichen:

var dauer = /(1?\d):([0-5]\d)/
var test = dauer.exec("abc2:45def")
document.write("Uhrzeit: " + test[0] + "<BR>") // 2:45
document.write("Stunden: " + test[1] + "<BR>") // 2
document.write("Minuten: " + test[2] + "<BR>") // 45

Das Objekt, das exec() zurückgibt, ist so etwas wie ein Array. Im Element mit dem Index 0 steht der Teil der Zeichenkette, auf den das Muster passt. Im Element mit dem Index 1 steht der Teil, der im Muster durch die ersten Klammern umgeben ist.

Mehrere Treffer

Oft ist es nicht nur von Bedeutung herauszufinden, ob in einer Zeichenkette ein Muster vorkommt und wie dieses eine Vorkommen aussieht, sondern auch, wie oft es vorkommt und wie diese Vorkommen denn aussehen. Für diese Zwecke ist die Methode match() des String-Objekts geeignet. Als Parameter kann dazu ein regulärer Ausdruck übergeben werden. Die Methode match() gibt alle Treffer in einem Array zurück. Sobald man dieses Array hat, kann man auf die herkömmliche Art und Weise die Ergebnisse auslesen.

An folgendem Beispiel soll dies gleich einmal verdeutlicht werden. Innerhalb einer Zeichenkette sollen alle Wörter herausgesucht werden, die den Buchstaben "e" nur einmal enthalten. Der zugehörige reguläre Ausdruck lautet "\b[a-df-zA-DF-Z]*e[a-df-zA-DF-Z]*\b". Er sieht kompliziert aus, bedeutet aber einfach, dass es sich um ein Wort handelt (angezeigt durch die Wortgrenzen am Anfang und am Ende), das ein e enthält und ansonsten aus weiteren Buchstaben ungleich e (also von a bis d und von f bis z) besteht. Des weiteren muss die Option "g" für globales Suchen angegeben werden, damit auch alle Vorkommen gefunden werden.

var nur_ein_e = /\b[a-df-zA-DF-Z]*e[a-df-zA-DF-Z]*\b/g
var satz = "Die Geister die ich rief ward ich nicht mehr los"
var liste = satz.match(nur_ein_e)
if (liste){
   document.write(liste.length + " Treffer gefunden!<BR>")
   for (var i=0; i<liste.length; i++)
      document.write(liste[i]+"<BR>")
} else
   document.write("Keine Treffer!")
Abbildung 12.6  Alle Wörter, die nur ein ’e’ enthalten
Abbildung

Suchen und ersetzen

Die letzte Anwendung für reguläre Ausdrücke, die hier vorgestellt werden soll, wird mit am häufigsten verwendet – wurde aber lange Zeit nur vom Netscape Navigator unterstützt. Man kann nicht nur nach Mustern suchen, sondern diese Muster auch durch andere Muster ersetzen. Ein Beispiel war die Umformung einer »deutschen« Dezimalzahl in die amerikanische Schreibweise. Dazu mussten alle Kommata durch Dezimalpunkte ersetzt werden. Der folgende Code erledigt das sehr einfach – aber eben leider nur bei Browsern der 4. Generation.

var komma = /,/g
var dezimalzahl_brd = "3,141592"
var dezimalzahl_usa = dezimalzahl_brd.replace(komma, ".")
document.write(dezimalzahl_usa) // 3.141592

Auch hier gibt es fortgeschrittenere Anwendungen. Ein weiterer Unterschied in der Schreibweise zwischen Deutschland und den USA besteht im Datum. Während das Format hierzulande meistens tt.mm.jj bzw. tt.mm.jjjj ist (t=Tag, m=Monat, j=Jahr), so verwendet man in den Vereinigten Staaten in der Regel jj-mm--tt bzw. jjjj-mm-tt. Die Aufgabe besteht jetzt darin, deutsche Datumsangaben durch das amerikanische Pendant zu ersetzen. Beginnen wir mit dem regulären Ausdruck für einen Datumswert. Das Jahr ist zwei- oder vierstellig, Monat und Tag sind aber unter Umständen einstellig. Außerdem dürfen als Werte für den Tag nur Werte von 1 bis 31, beim Monat nur Werte von 1 bis 12 verwendet werden (unmögliche Daten wie etwa dem 30. Februar werden hier übergangen, um das Beispiel einfach zu halten). Der Ausdruck sieht also recht kompliziert aus, aber die Idee, die dahintersteht, ist recht einfach. Probieren Sie es doch einmal mit indexOf()!

var datum = /\b(0?[1-9]|[12][0-9]|3[01])\.(0?[1-9]|1[0-2])\.
  (\d?\d?\d\d)\b/

Wie Sie sehen, wurden um Tag, Monat und Jahr runde Klammern eingefügt. Der Sinn des ganzen zeigt sich bei der Übersetzung in das amerikanische Format. Die Jahreszahl muss nach vorn, der Tag nach hinten. Während beim Ergebnis der Methode exec() die Inhalte der Klammern in ergebnisarry[1], ergebnisarray[2] und so weiter stehen, findet man die Inhalte der Klammern bei regulären Ausdrücken in den speziellen Variablen $1, $2 und so weiter. Mit folgendem Code wandelt man ein deutsches Datum in das amerikanische Format um.

function deutsch_zu_usa(d){
   var datum = /\b(0?[1-9]|[12][0-9]|3[01])\.(0?[1-9]|1[0-2])\.
     (\d?\d?\d\d)\b/
   if (datum.test(d))
      return d.replace(datum, "$3-$2-$1")
   else
      return d
}
document.write(deutsch_zu_usa("Das dritte Jahrtausend 
beginnt am 1.1.01 – und keinen Tag früher"))

Mit d.replace(datum, "$3-$2-$1") wird der reguläre Ausdruck auf die Eingabe angewandt. In der dritten Klammer, also in $3, steht die Jahreszahl, in $2 der Monat und in $1 der Tag. Die Ausgabe lautet dann: "Das dritte Jahrtausend beginnt am 01-1-1 – und keinen Tag früher". In der Variablen $0 steht übrigens analog zu exec() der gesamte Treffer, in diesem Fall also "1.1.2001".

Die Funktion replace() gibt es auch in einer Luxusvariante. Wie beim Netscape-Pendant auch werden an replace() zwei Parameter übergeben. Die erste ist ein regulärer Ausdruck, und der zweite ist eine Funktion, welche vom JavaScript-Interpreter automatisch beim Aufruf von replace() aufgerufen wird. An diese Funktion werden (vom JavaScript-Interpreter!) die folgenden Parameter übergeben (in der angegebenen Reihenfolge):

gp  Die Zeichenkette, die auf das Muster passt.
gp  Der Reihe alle Untermuster. Wenn im regulären Ausdruck Klammern verwendet worden sind, werden die Entsprechungen in diesen Klammern (also die Werte von $1, $2 usw.) an die Funktion übergeben.
gp  Die Position, an der das Muster in der zu überprüfenden Zeichenkette gefunden wurde.
gp  Die überprüfte Zeichenkette.

Die Funktion, die von replace() aufgerufen wird, muss nun nur noch folgendes leisten: Einen Wert zurückliefern. Durch diesen Wert wird das gefundene Muster in der zu überprüfenden Zeichenkette ersetzt.

Das Beispiel von oben – die Umformung des Datums in ein amerikanisches Format – kann folgendermaßen angepasst werden:

function deutsch_zu_usa(d){
   var datum = /\b(0?[1-9]|[12][0-9]|3[01])\.(0?[1-9]|1[0-2])\.
     (\d?\d?\d\d)\b/
   if (datum.test(d))
      return d.replace(datum, d_zu_usa)
   else
      return d
}
function d_zu_usa(str, m1, m2, m3, pos, quelle){
   return m3+"-"+m2+"-"+m1 //entspricht $3-$2-$1
}
document.write(deutsch_zu_usa("Das dritte Jahrtausend 
beginnt am 1.1.01 – und keinen Tag früher"))

Microsoft hat die replace()-Funktion erst in Version 5.5 (wie bereits erwähnt im Beta-Stadium) des Internet Explorer eingebaut, mit früheren Versionen, inklusive der momentan aktuellen Version 5, funktioniert das noch nicht.

Neues in JavaScript 1.5

In JavaScript 1.5, was zur Zeit nur vom Netscape 6 unterstützt wird, erhält der Fragezeichenoperator ? eine weitere Bedeutung. Normalerweise arbeitet die Mustererkennung bei einem regulären Ausdruck »gierig«, sprich: Es wird ein möglichst großer Treffer zurückgeliefert. Hier ein Beispiel:

var htmltag = /(<.*>)/
var test = htmltag.exec("<p>JavaScript</p>")
test[0] = test[0].replace("<", "&lt;")
test[0] = test[0].replace(">", "&gt;")
document.write("HTML-Tag: " + test[0])

Was gibt dieses Programm aus? Vielleicht erwarten Sie als Ausgabe "<p>", denn das würde auf das angegebene Muster passen. Doch leider falsch gedacht, denn es wird wie gesagt immer ein möglichst großer Treffer zurückgeliefert, in diesem Falle also "<p>JavaScript</p>". Wenn Sie einen möglichst kleinen Treffer möchten, müssen Sie direkt nach einem Sonderzeichen zum Zählen (*, +, ?, {}) den Fragezeichenoperator angeben. Folgender Code würde also in der Tat "<p>" ausgeben:

var htmltag = /(<.*?>)/
var test = htmltag.exec("<p>JavaScript</p>")
test[0] = test[0].replace("<", "&lt;")
test[0] = test[0].replace(">", "&gt;")
document.write("HTML-Tag: " + test[0])

Wenn Sie diesen Code mit dem Netscape Navigator 4.x oder dem Internet Explorer 5.0x oder kleiner ausführen, erhalten Sie entweder ein falsches Ergebnis oder eine Fehlermeldung. Der Internet Explorer 5.5 unterstützt zwar kein JavaScript 1.5, hat aber diese Erweiterung der Syntax für reguläre Ausdrücke auch im Programm.

Abbildung 12.7  Netscape 6 interpretiert den regulären Ausdruck richtig
Abbildung


Galileo Computing

12.5 Fragen & Aufgaben  toptop

1. Ändern Sie das Buchbestellungsformular so um, dass die URL der folgenden Seite »von Hand« erzeugt wird statt durch den Browser beim Absenden des Formulars.
2. Ändern Sie das Beispiel mit den zwei Auswahllisten so um, dass die Link-Ziele im VALUE-Attribut (bzw. der Eigenschaft value der Option) gespeichert werden.
3. Überlegen Sie sich, wir man überprüfen könnte, ob eine Email-Adresse gültig ist. Schreiben Sie eine einfache Überprüfungsfunktion, die aber JavaScript 1.0-kompatibel sein sollte.
4. Geben Sie reguläre Ausdrücke an für:
    gp  Vierbuchstabige Wörter
    gp  Gerade, positive Zahlen
    gp  (Vierstellige) Jahreszahlen des 20. Jahrhunderts
    gp  Email-Adressen (muss nicht allzu strikt sein)
5. Schreiben Sie ein JavaScript-Programm, das eine (beliebige) Stundenangabe im Format 12:35 annimmt und dann die Entlohnung bei einem Stundensatz von 8 DM ausgibt – in deutschem Format. Reguläre Ausdrücke dürfen verwendet werden.
6. Schreiben Sie eine JavaScript-Funktion, die in einer Zeichenkette alle dreibuchstabigen Wörter durch die Zeichenkette "$0" ersetzt.
7. Schreiben Sie das letzte Beispiele in diesem Kapitel (Suche nach HTML-Tag) so um, dass es auch im Netscape 4.x und im Internet Explorer 5.0x oder kleiner funktioniert! Verwenden Sie dabei aber einen regulären Ausdruck.





1    Natürlich gibt es reguläre Ausdrücke schon viel länger, aber mit der Verbreitung von Perl stieg auch die Verbreitung von regulären Ausdrücken.

  

Perl – Der Einstieg




Copyright © Galileo Press GmbH 2001 - 2002
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken und speichern. Ansonsten unterliegt das <openbook> denselben Bestimmungen wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.
Die Veröffentlichung der Inhalte oder Teilen davon bedarf der ausdrücklichen schriftlichen Genehmigung von Galileo Press. Falls Sie Interesse daran haben sollten, die Inhalte auf Ihrer Website oder einer CD anzubieten, melden Sie sich bitte bei: stefan.krumbiegel@galileo-press.de


[Galileo Computing]

Galileo Press GmbH, Gartenstraße 24, 53229 Bonn, fon: 0228.42150.0, fax 0228.42150.77, info@galileo-press.de