Zum Inhalt
wannacode

Strings: mit Text arbeiten

Kurz gesagt: Ein String (Zeichenkette) ist Text, eine Folge von Zeichen mit Indizes ab 0: Er hat eine Länge und Methoden zum Suchen, Ersetzen, Ausschneiden, Aufteilen und Vergleichen.

Problem

Der Code stimmt, aber er wird nicht angenommen

Der Shop gibt mit dem Code SOMMER10 10% Rabatt. Ein Kunde schreibt ihn aus der Werbung ab. Er tippt ihn aber in Kleinbuchstaben und setzt aus Versehen ein Leerzeichen davor:

const code = await ask("");
if (code === "SOMMER10") {
console.log("10% Rabatt");
} else {
console.log("Ungültiger Code");
}
rl.close();
Eingabe
sommer10
Ausgabe
Ungültiger Code

Für einen Menschen ist es derselbe Code. Für das Programm sind sommer10 und SOMMER10 verschiedene Texte: Der erste hat ein Zeichen mehr, und die Buchstaben sind andere. Du musst in einen Text hineinschauen und ihn reparieren können.

Die Idee

Text ist eine Folge von Zeichen

Text besteht aus Zeichen, die nacheinander stehen: Buchstaben, Ziffern, Leerzeichen, Satzzeichen. Jedes Zeichen hat einen Index, wie in einem Array. Das erste hat den Index 0.

const code = "SOMMER10";
console.log(code.length);
console.log(code[0]);
console.log(code[code.length - 1]);
Ausgabe
8
S
0
  • code.length ist die Anzahl der Zeichen.
  • code[0] ist das Zeichen mit dem Index 0. Das letzte Zeichen hat den Index length - 1.

Einen eigenen Typ für ein einzelnes Zeichen gibt es hier nicht (in Java und C# heißt er char). Ein Zeichen ist ein Text der Länge 1. Einfache und doppelte Anführungszeichen machen dasselbe: 'S' und "S" sind derselbe Text.

const code = "SOMMER10";
console.log(code.at(-1));
console.log(code[-1]);
console.log(typeof code[0]);
console.log(code[0].length);
console.log('S' === "S");
Ausgabe
0
undefined
string
1
true

code.at(-1) ist das letzte Zeichen: Ein negativer Index zählt von hinten. Mit eckigen Klammern geht das nicht: code[-1] ergibt undefined.

Bei Text und bei Arrays ist die Länge length, ohne Klammern.

Sieh es dir an

Zeichen für Zeichen

Wie viele Ziffern hat die Telefonnummer? Du gehst mit einer Schleife durch die Indizes von 0 bis zum letzten und schaust dir jedes Zeichen an:

const phone = "0888 123 456";
let digits = 0;
for (let i = 0; i < phone.length; i++) {
const c = phone[i];
if (c >= "0" && c <= "9") {
digits++;
}
}
console.log("Ziffern: " + digits);
Ausgabe
Ziffern: 10

c >= "0" && c <= "9" funktioniert, weil jedes Zeichen einen Code hat: eine Zahl in der Zeichentabelle. Texte werden nach den Codes ihrer Zeichen verglichen. Die Ziffern von "0" bis "9" haben aufeinanderfolgende Codes, die Buchstaben von "a" bis "z" auch.

Genauer, für Neugierige
  • Fertige Methoden wie „ist das eine Ziffer“ gibt es nicht. Für eine Ziffer vergleichst du wie oben. Für einen Buchstaben gilt: Ein Zeichen ist ein Großbuchstabe, wenn c !== c.toLowerCase() (seine kleine Form ist anders), und ein Kleinbuchstabe, wenn c !== c.toUpperCase(). Das funktioniert auch mit Umlauten wie ä.
  • "A".charCodeAt(0) gibt den Code eines Zeichens, also 65. Umgekehrt ist String.fromCharCode(66) das Zeichen "B". Vorsicht: "a" + 1 ist kein Fehler, sondern der Text "a1".
  • Ohne Index: for (const c of phone) geht direkt durch die Zeichen des Textes.
const c = "Ä";
console.log(c >= "0" && c <= "9");
console.log(c.toUpperCase() !== c.toLowerCase());
console.log(c !== c.toLowerCase());
console.log("ä" !== "ä".toUpperCase());
console.log("A".charCodeAt(0), String.fromCharCode(66));
console.log("a" + 1);
let digits = 0;
for (const ch of "0888 123 456") {
if (ch >= "0" && ch <= "9") {
digits++;
}
}
console.log(digits);
Ausgabe
false
true
true
true
65 B
a1
10

Probier es aus

Welches Zeichen?

Was gibt das Programm aus?

const word = "Auftrag";
console.log(word[3]);
console.log(word.length);
Antwort

Die Idee

Die Methoden von Text

Text bringt fertige Methoden mit: Aktionen, die du mit einem Punkt hinter dem Text aufrufst. Hier ist die Reparatur für den Gutscheincode:

const code = " sommer10";
const clean = code.trim().toUpperCase();
console.log("[" + clean + "]");
console.log(clean === "SOMMER10");
Ausgabe
[SOMMER10]
true

trim() entfernt die Leerzeichen vorne und hinten. toUpperCase() macht alle Buchstaben groß. Methoden lassen sich hintereinander aufrufen: Die erste gibt einen Text zurück, und auf ihm wird die zweite aufgerufen.

Noch ein paar, an einer E-Mail-Adresse:

const email = "ivan.petrov@mail.bg";
console.log(email.includes("@"));
console.log(email.indexOf("@"));
console.log(email.slice(0, email.indexOf("@")));
console.log(email.replaceAll(".", " "));
console.log(email.endsWith(".bg"));
Ausgabe
true
11
ivan.petrov
ivan petrov@mail bg
true
Methode Was sie macht
includes(x) ob x darin vorkommt
indexOf(x) der Index, an dem x zum ersten Mal steht (-1, wenn es fehlt)
slice(a, b) ein Teil des Textes
replaceAll(x, y) jedes x wird durch y ersetzt
startsWith(x), endsWith(x) ob er mit x beginnt (endet)
toLowerCase() alle Buchstaben klein

Vorsicht mit replace: In JavaScript ersetzt es nur das erste Vorkommen. Für alle schreibst du replaceAll.

console.log("ivan.petrov@mail.bg".replace(".", " "));
console.log("ivan.petrov@mail.bg".indexOf("#"));
console.log("Brot".startsWith("B"));
console.log("Brot".toLowerCase());
Ausgabe
ivan petrov@mail.bg
-1
true
brot
Genauer, für Neugierige

slice(a, b) nimmt die Zeichen von Index a bis Index b, ohne b. Ihre Anzahl ist b - a. Mit nur einem Argument nimmt es alles bis zum Ende. Ein negativer Index zählt von hinten: slice(-2) sind die letzten zwei Zeichen.

const date = "2026-10-24";
console.log(date.slice(5, 7));
console.log(date.slice(8));
console.log(date.slice(-2));
Ausgabe
10
24
24

Die Idee

Text ändert sich nicht

Es gibt eine Eigenheit, die am Anfang alle verwirrt:

let name = "maria";
name.toUpperCase();
console.log(name);
name = name.toUpperCase();
console.log(name);
Ausgabe
maria
MARIA

Die zweite Zeile bewirkt nichts Sichtbares. toUpperCase() ändert name nicht. Es erzeugt einen neuen Text in Großbuchstaben und gibt ihn zurück. Niemand speichert ihn, und er geht verloren.

Ein Text kann nach dem Erzeugen nicht mehr geändert werden. Man sagt, er ist unveränderlich (immutable). Jede Methode, die einen Text „ändert“, gibt in Wirklichkeit einen neuen zurück. Um ihn zu behalten, weist du ihn zu: name = name.toUpperCase();.

let name = "maria";
name.toUpperCase();
console.log(name);
name = name.toUpperCase();
console.log(name);
Schritt für Schritt, in Worten
  1. In name steht der Text „maria“: 5 Zeichen mit den Indizes 0 bis 4.
  2. toUpperCase() rührt „maria“ nicht an. Es erzeugt einen neuen Text, „MARIA“.
  3. Niemand speichert den neuen Text, und er geht verloren.
  4. In name steht immer noch „maria“, und das wird ausgegeben.
  5. Wieder ein neuer Text, „MARIA“, aber jetzt speichert = ihn in name. Das alte „maria“ fällt weg.
  6. Jetzt steht in name „MARIA“.
Genauer, für Neugierige
  • Auch mit einem Index kannst du kein Zeichen im Text ändern. name[0] = "M" bleibt in einem normalen Skript still: Es gibt keinen Fehler, aber name ist immer noch "maria". In einer Datei mit import (einem Modul) stoppt dieselbe Zeile das Programm mit TypeError: Cannot assign to read only property '0' of string. Du erzeugst einen neuen Text, zum Beispiel "M" + name.slice(1).
  • Wenn du viele Teile hast, sammle sie in einem Array und füge sie mit join auf einmal zusammen:
const parts = ["Milch", "Brot", "Eier"];
console.log(parts.join(", "));
Ausgabe
Milch, Brot, Eier

Probier es aus

Finde den Fehler

Der Benutzer gibt seine E-Mail mit Großbuchstaben und Leerzeichen ein. Das Programm soll sie bereinigen und ihn hereinlassen. Es sagt aber „Diesen Benutzer gibt es nicht.“. In welcher Zeile ist der Fehler?

Wähle die Zeile mit dem Fehler.

Die Idee

Text in Teilen

Oft enthält ein Text mehrere Dinge, getrennt durch ein Zeichen: Artikel durch ein Komma, Wörter durch ein Leerzeichen. split teilt ihn in Teile und gibt ein Array von Texten zurück:

const list = "Milch,Brot,Eier,Käse";
const items = list.split(",");
console.log("Artikel: " + items.length);
for (let i = 0; i < items.length; i++) {
console.log((i + 1) + ". " + items[i]);
}
Ausgabe
Artikel: 4
1. Milch
2. Brot
3. Eier
4. Käse

Das Trennzeichen gehört nicht zu den Teilen. Ab hier arbeitest du mit einem normalen Array: Länge, Indizes, Schleife.

So liest du auch eine ganze Zeile mit Zahlen von der Tastatur: Du teilst sie auf und wandelst jeden Teil in eine Zahl um. Genau das hat dir in der letzten Lektion über Tabellen gefehlt:

const parts = (await ask("")).split(" ");
let sum = 0;
for (const p of parts) {
sum += Number(p);
}
console.log(sum);
rl.close();
Eingabe
42 38 51 47 60
Ausgabe
238
Genauer, für Neugierige
  • Zwei Leerzeichen nebeneinander ergeben einen leeren Teil '' dazwischen. split(/ +/) (ein oder mehrere Leerzeichen) löst das. Das zwischen den Schrägstrichen ist ein regulärer Ausdruck, ein Muster für Text. Sonst bekommt split normalen Text, und split(".") teilt an einem Punkt.
  • Das Gegenteil von split ist items.join(", "): Es fügt die Teile mit einem Trennzeichen zusammen.
console.log("a b".split(" "));
console.log("a b".split(/ +/));
console.log("a.b".split("."));
console.log(["a", "b"].join(", "));
Ausgabe
[ 'a', '', 'b' ]
[ 'a', 'b' ]
[ 'a', 'b' ]
a, b

Probier es aus

Ist es dasselbe?

In JavaScript vergleicht === den Inhalt von Texten, Buchstabe für Buchstabe. Aber ein Groß- und ein Kleinbuchstabe sind verschiedene Zeichen. Die Eingabe ist Sofia:

Was gibt das Programm aus?

const city = await ask("");
console.log(city === "Sofia");
console.log(city === "sofia");
console.log(city.toLowerCase() === "sofia");
rl.close();
Antwort
Genauer, für Neugierige

Es gibt auch == mit zwei Gleichheitszeichen. Es wandelt zuerst beide Seiten in einen Typ um und vergleicht erst dann. Deshalb sind der Text "1" und die Zahl 1 gleich:

console.log("1" == 1);
console.log("1" === 1);
Ausgabe
true
false

Vergleiche immer mit ===.

Übung

Namen und Wörter

Löse die Aufgaben in deinem Editor. Der Text wird als ganze Zeile von der Tastatur gelesen.

1. Der Name rückwärts. Lies einen Namen ein und gib ihn von hinten nach vorne aus. Du gehst durch die Indizes vom letzten bis 0 und hängst die Zeichen an einen neuen Text an.

Eingabe
Maria
Ausgabe
airaM

2. Anzahl der Wörter. Lies einen Satz ein und zähle die Wörter. Zwischen den Wörtern kann mehr als ein Leerzeichen stehen, und am Anfang und am Ende können Leerzeichen sein. Tipp: Ein Wort beginnt dort, wo das Zeichen kein Leerzeichen ist und das davor ein Leerzeichen ist (oder es davor keines gibt).

Eingabe
Heute ist ein Feiertag
Ausgabe
Wörter: 4

3. Palindrom. Ein Palindrom liest sich von vorne nach hinten und von hinten nach vorne gleich. Leerzeichen und Großbuchstaben zählen nicht. Entferne die Leerzeichen, mach die Buchstaben klein und vergleiche das erste Zeichen mit dem letzten, das zweite mit dem vorletzten und so weiter.

Eingabe
Ein Esel lese nie
Ausgabe
Es ist ein Palindrom
Eingabe
Kaffee mit Milch
Ausgabe
Kein Palindrom

Übung

Prüfen und zählen

4. Sicheres Passwort. Frag nach einem Passwort, bis der Benutzer ein sicheres eingibt: mindestens 8 Zeichen, mindestens eine Ziffer, ein Groß- und ein Kleinbuchstabe. Sag nach jedem schwachen Passwort, was verlangt wird. Tipp: do-while und eine Prüfung jedes Zeichens: eine Ziffer mit c >= "0" && c <= "9", ein Großbuchstabe mit c !== c.toLowerCase(), ein Kleinbuchstabe mit c !== c.toUpperCase().

Eingabe
kaffee
kaffee2026
Kaffee2026
Ausgabe
Passwort:
Schwaches Passwort: mindestens 8 Zeichen, eine Ziffer, ein Groß- und ein Kleinbuchstabe.
Passwort:
Schwaches Passwort: mindestens 8 Zeichen, eine Ziffer, ein Groß- und ein Kleinbuchstabe.
Passwort:
Passwort akzeptiert.

Weitere Aufgaben

  • Kommas statt Leerzeichen. Lies einen Satz ein und ersetze jedes Leerzeichen durch ein Komma. Morgen fahren wir nach Varna → Morgen,fahren,wir,nach,Varna.
  • Der längste Name. Lies durch Kommas getrennte Namen ein und gib den längsten aus. Ana,Kristina,Peter → Kristina.
  • Vokale als Sternchen. Ersetze jeden Vokal (a, e, i, o, u) durch *, egal ob groß oder klein. Ich trinke Kaffee → *ch tr*nk* K*ff**.
  • Häufigkeit der Buchstaben. Zähle, wie oft jeder Buchstabe im Text vorkommt, ohne Unterschied zwischen groß und klein. Tipp: ein Array mit 26 Zählern, einer für jeden Buchstaben von 'a' bis 'z' (Umlaute und ß lässt du weg). Der Index des Buchstabens c ist c.charCodeAt(0) - "a".charCodeAt(0). Gib nur die Buchstaben aus, die vorkommen.
  • Zeichendiagramm. Wie die Aufgabe oben, aber statt der Zahl gibst du so viele Sternchen aus: a: ****.
  • Wie oft jedes Wort. Lies einen Satz ein und gib für jedes verschiedene Wort aus, wie oft es vorkommt. Tipp: Teile ihn in Wörter auf und prüfe für jedes Wort, ob es schon weiter vorne im Array gezählt wurde.
  • Nach Länge sortieren. Lies durch Leerzeichen getrennte Wörter ein und gib sie vom kürzesten bis zum längsten aus. Sortiere das Array so, wie du Zahlen sortiert hast, aber vergleiche die Längen.
  • Anzahl der Sätze. Zähle die Sätze in einem Text: Jeder endet mit ., ! oder ?. Achte auf ... und ?!: Sie beenden einen Satz, nicht drei.
  • Ausgeglichene Klammern. Prüfe, ob die Klammern in einem Text ausgeglichen sind. Bei einer Art von Klammern reicht ein Zähler: ( addiert 1, ) zieht 1 ab. Der Zähler darf nie unter 0 fallen, und am Ende muss er 0 sein. Bei drei Arten, (), [], {}, brauchst du ein Array von Zeichen, in dem du die offenen Klammern aufbewahrst, und einen Zähler, wie voll es ist. Bei einer schließenden Klammer muss die letzte offene von derselben Art sein. {[()]} ist ausgeglichen, ([)] nicht.

Test

Teste dich

1. Was ergibt "Brot".length?
2. Was macht die Zeile name.toUpperCase(); allein, ohne Zuweisung?
3. Was ergibt "Varna" === "varna" in JavaScript?
4. Was ist der Unterschied zwischen 'a' und "a" in JavaScript?
5. Was ergibt "Mo,Mi,Fr".split(",")?

Erstellt von Ivo Gergov im Rahmen der Kampagne von Evo Tech für zugängliche Programmierausbildung ·