mitmario.dev

Zeichenklassen und Wiederholungen

JavaScript Im Browser 3 Min Lesezeit 4 BeispieleLektion 2 von 6

In Lektion 9.1 stand ein einziges Sonderzeichen, das \d. Jetzt kommt der Rest davon: welche Zeichen an einer Stelle stehen dürfen und wie oft. Mehr braucht man für Formularprüfungen selten.

Die fertigen Klassen

Die fertigen Klassen
const probe = "Kurs 3, Teil A";

// \d eine Ziffer, \w ein Wortzeichen, \s ein Leerraum.
console.log("Ziffern:", probe.replace(/\d/g, "#"));
console.log("Wortzeichen:", probe.replace(/\w/g, "#"));
console.log("Leerraum:", probe.replace(/\s/g, "#"));

// Der Punkt steht für fast jedes Zeichen.
console.log("Punkt:", probe.replace(/./g, "#"));

// Groß geschrieben ist es das Gegenteil.
console.log("kein Wortzeichen:", probe.replace(/\W/g, "#"));
console.log("keine Ziffer:", probe.replace(/\D/g, "#"));

// Und ein Punkt, den man wirklich meint, braucht einen Backslash.
console.log("echter Punkt:", "a.b.c".replace(/\./g, "#"));

Vier Kürzel decken die häufigsten Fälle ab. \d ist eine Ziffer, \w ein Wortzeichen (Buchstabe, Ziffer oder Unterstrich), \s ein Leerraum (Leerzeichen, Tabulator, Zeilenumbruch). Der Punkt steht für fast jedes Zeichen.

Groß geschrieben bedeutet jedes davon das Gegenteil: \D ist alles außer einer Ziffer, \W alles außer einem Wortzeichen, \S alles außer Leerraum. Das ist bequem und man liest es leicht falsch, deshalb lohnt sich beim Lesen fremder Muster ein zweiter Blick auf die Schreibweise.

Ein Punkt, den du wirklich meinst, braucht einen Backslash. /./ passt auf alles, /\./ nur auf den Punkt. Dasselbe gilt für die anderen Sonderzeichen: Backslash davor, und sie meinen sich selbst.

Eigene Klassen

Eigene Klassen in eckigen Klammern
// In eckigen Klammern steht, was an dieser einen Stelle
// stehen darf. Eine der aufgezählten Möglichkeiten, nicht alle.
console.log(/[abc]/.test("nur b hier"));
console.log(/[abc]/.test("nur x hier"));

// Ein Bindestrich macht daraus einen Bereich.
console.log("Kleinbuchstaben:", "Kurs 3".replace(/[a-z]/g, "#"));
console.log("Buchstaben:", "Kurs 3".replace(/[A-Za-z]/g, "#"));

// Ein ^ an erster Stelle kehrt die Klasse um.
console.log("alles außer Ziffern:", "Kurs 3".replace(/[^0-9]/g, "#"));

// In der Klasse verlieren die meisten Sonderzeichen ihre
// Bedeutung. Der Punkt ist dort einfach ein Punkt.
console.log("Klasse mit Punkt:", "a.b".replace(/[.]/g, "#"));

In eckigen Klammern schreibst du selbst auf, was an einer Stelle stehen darf. [abc] passt auf ein a, ein b oder ein c, nicht auf alle drei hintereinander.

Ein Bindestrich macht daraus einen Bereich: [a-z] sind die Kleinbuchstaben, [0-9] dasselbe wie \d, und [A-Za-z] sind alle Buchstaben ohne Umlaute.

Ein ^ an erster Stelle kehrt die Klasse um: [^0-9] passt auf alles, was keine Ziffer ist. Das ^ bedeutet nur an dieser Stelle „nicht”, überall sonst im Muster heißt es „Anfang”, und das ist Lektion 9.3.

Innerhalb der eckigen Klammern verlieren die meisten Sonderzeichen ihre Bedeutung. Der Punkt ist dort einfach ein Punkt, ein Backslash ist also nicht nötig.

Wie oft

Wie oft
// Die Mengenangabe steht hinter dem, worauf sie sich bezieht.
console.log("* keins oder mehr:", /ab*c/.test("ac"), /ab*c/.test("abbbc"));
console.log("+ eins oder mehr:", /ab+c/.test("ac"), /ab+c/.test("abbbc"));
console.log("? keins oder eins:", /ab?c/.test("ac"), /ab?c/.test("abbc"));

// Genau, mindestens, oder von bis.
console.log("genau 5:", /^\d{5}$/.test("04103"), /^\d{5}$/.test("4103"));
console.log("2 bis 4:", /^\d{2,4}$/.test("123"), /^\d{2,4}$/.test("12345"));
console.log("ab 2:", /^\d{2,}$/.test("1"), /^\d{2,}$/.test("123456"));

// Ohne Mengenangabe steht dort genau ein Zeichen.
console.log("nur eins:", /^\d$/.test("7"), /^\d$/.test("77"));

Die Mengenangabe steht hinter dem, worauf sie sich bezieht, und bezieht sich immer nur auf das eine Zeichen davor (oder auf eine Gruppe, siehe Lektion 9.3).

* heißt keins oder mehr, + heißt eins oder mehr, ? heißt keins oder eins. Der Unterschied zwischen * und + ist genau der leere Fall, und der entscheidet öfter, als man denkt: /\d*/ passt auch auf einen Text ganz ohne Ziffern.

In geschweiften Klammern wirst du genauer. {5} heißt genau fünf, {2,4} heißt zwei bis vier, {2,} heißt mindestens zwei. Eine Postleitzahl ist \d{5}, und das ist gleich die Aufgabe.

Steht keine Mengenangabe da, heißt das genau ein Zeichen.

Im Beispiel steht bei den Prüfungen ein ^ vorn und ein $ hinten. Die beiden machen das Muster am Anfang und am Ende des Textes fest, damit \d{5} nicht auch in einer längeren Zahl irgendwo passt. Warum das bei jeder Prüfung dazugehört, ist Lektion 9.3. Bis dahin schreibst du sie einfach mit.

Gierig, und die Umlaut-Falle

Gierig, und was das Fragezeichen ändert
const text = "<b>fett</b> und <i>kursiv</i>";

// + und * nehmen so viel wie möglich. Der erste Treffer geht
// deshalb bis zum letzten spitzen Klammerpaar.
console.log("gierig:", text.replace(/<.+>/, "[TAG]"));

// Ein ? dahinter macht sie genügsam: so wenig wie möglich.
console.log("genügsam:", text.replace(/<.+?>/, "[TAG]"));
console.log("alle:", text.replace(/<.+?>/g, "[TAG]"));

// Umlaute fallen nicht unter \w. Das ist die Falle in
// deutschen Mustern.
console.log("Jörg mit \\w:", /^\w+$/.test("Jörg"));
console.log("Jörg mit Klasse:", /^[A-Za-zÄÖÜäöüß]+$/.test("Jörg"));

// Und mit Bindestrich im Namen.
const name = /^[A-Za-zÄÖÜäöüß]+(-[A-Za-zÄÖÜäöüß]+)*$/;
console.log("Jörg-Uwe:", name.test("Jörg-Uwe"), "| Jörg2:", name.test("Jörg2"));

+ und * sind gierig: sie nehmen so viel, wie sie können. /<.+>/ auf <b>fett</b> beginnt beim ersten < und läuft bis zum letzten >, also über den ganzen Text. Beim ersten Mal erwartet das niemand.

Ein ? hinter der Mengenangabe macht sie genügsam: dann nimmt sie so wenig wie möglich, und /<.+?>/ trifft genau ein Tag. Verwechsle dieses ? nicht mit dem ? als Mengenangabe, es ist dieselbe Taste in zwei Rollen.

Und jetzt die Falle, die im Deutschen jeden trifft: Umlaute fallen nicht unter \w. Ein /^\w+$/ lehnt „Jörg” ab, und zwar ohne Hinweis darauf, woran es lag. \w meint die Buchstaben A bis Z, a bis z, die Ziffern und den Unterstrich, mehr nicht.

Für deutsche Namen führst du die Umlaute deshalb ausdrücklich auf: [A-Za-zÄÖÜäöüß]. Das ist unschön und es ist die ehrliche Fassung. Wer es genauer braucht, nimmt \p{L} mit dem Flag u, aber dann steht im Muster wieder etwas, das ohne Nachschlagen niemand liest.

Zum Mitnehmen

Umlaute fallen nicht unter \w. In einem deutschen Muster musst du sie ausdrücklich aufführen, sonst fällt jeder Jörg durch deine Namensprüfung.

Jetzt du

Basis Konto, kostenlos

Zu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.

Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.

Was in dieser Lektion steckt

  • Artikel mit 4 Beispielen zum Ausprobieren

    Steht hier, ohne Konto lesbar.

  • Aufgabe im Editor, direkt im Browser geprüft

    Öffnet sich mit dem Basis Konto.