Start · Sprachen · JavaScript · Referenz · RegExp

RegExp

Klasse

Das <code>RegExp</code>-Objekt wird verwendet, um Text mit einem Muster abzugleichen.

seit JavaScript ES1 Kategorie: core

Signatur

new RegExp(pattern, flags?) / RegExp(pattern, flags?) / /pattern/flags

Beschreibung

Das RegExp-Objekt wird verwendet, um Text mit einem Muster abzugleichen.

Eine Einführung in reguläre Ausdrücke finden Sie im Kapitel Regular expressions des JavaScript-Guides. Ausführliche Informationen zur Syntax regulärer Ausdrücke finden Sie in der Referenz zu regulären Ausdrücken.

Literal-Notation und Konstruktor

Es gibt zwei Möglichkeiten, ein RegExp-Objekt zu erstellen: eine Literal-Notation und einen Konstruktor.

  • Die Literal-Notation nimmt ein Muster zwischen zwei Schrägstrichen entgegen, gefolgt von optionalen Flags nach dem zweiten Schrägstrich.
  • Die Konstruktorfunktion nimmt entweder einen String oder ein RegExp-Objekt als ersten Parameter und einen String mit optionalen Flags als zweiten Parameter entgegen.

Bevor reguläre Ausdrücke verwendet werden können, müssen sie kompiliert werden. Dieser Vorgang erlaubt es ihnen, Abgleiche effizienter durchzuführen.

Die Literal-Notation führt zur Kompilierung des regulären Ausdrucks, wenn der Ausdruck ausgewertet wird. Der Konstruktor des RegExp-Objekts, new RegExp('ab+c'), führt hingegen zu einer Kompilierung des regulären Ausdrucks zur Laufzeit.

Verwenden Sie einen String als erstes Argument des RegExp()-Konstruktors, wenn Sie den regulären Ausdruck aus dynamischer Eingabe erstellen möchten.

Flags im Konstruktor

Der Ausdruck new RegExp(/ab+c/, flags) erzeugt ein neues RegExp anhand der Quelle (source) des ersten Parameters und der durch den zweiten Parameter bereitgestellten Flags.

Beim Verwenden der Konstruktorfunktion sind die üblichen String-Escape-Regeln (Sonderzeichen mit \ voranstellen, wenn sie in einem String enthalten sind) notwendig.

Spezielle Behandlung für Regexes

Ob etwas ein „Regex" ist, kann per duck-typing bestimmt werden. Es muss nicht zwingend ein RegExp sein.

Einige eingebaute Methoden behandeln Regexes speziell. Sie entscheiden anhand mehrerer Schritte, ob x ein Regex ist:

  1. x muss ein Objekt sein (kein Primitiv).
  2. Wenn x[Symbol.match] nicht undefined ist, wird geprüft, ob es truthy ist.
  3. Andernfalls, wenn x[Symbol.match] undefined ist, wird geprüft, ob x mit dem RegExp-Konstruktor erstellt wurde. (Dieser Schritt sollte selten vorkommen, denn wenn x ein unverändertes RegExp-Objekt ist, sollte es eine Symbol.match-Eigenschaft besitzen.)

Beachten Sie, dass in den meisten Fällen die Symbol.match-Prüfung greift, was bedeutet:

  • Ein tatsächliches RegExp-Objekt, dessen Symbol.match-Eigenschaft einen falsy Wert außer undefined hat (auch wenn ansonsten alles intakt ist, wie exec und [Symbol.replace]()), kann so verwendet werden, als wäre es kein Regex.
  • Ein Nicht-RegExp-Objekt mit einer Symbol.match-Eigenschaft wird so behandelt, als wäre es ein Regex.

Diese Entscheidung wurde getroffen, weil [Symbol.match]() die aussagekräftigste Eigenschaft dafür ist, dass etwas zum Abgleichen verwendet werden soll. (exec könnte ebenfalls verwendet werden, aber da es keine Symbol-Eigenschaft ist, gäbe es zu viele falsch-positive Treffer.) Zu den Stellen, die Regexes speziell behandeln, gehören:

  • String.prototype.endsWith(), startsWith() und includes() werfen einen TypeError, wenn das erste Argument ein Regex ist.
  • String.prototype.matchAll() und replaceAll() prüfen, ob das global-Flag gesetzt ist, wenn das erste Argument ein Regex ist, bevor dessen [Symbol.matchAll]()- oder [Symbol.replace]()-Methode aufgerufen wird.
  • Der RegExp()-Konstruktor gibt das pattern-Argument direkt zurück, wenn pattern ein Regex ist (neben einigen weiteren Bedingungen). Ist pattern ein Regex, werden auch dessen source- und flags-Eigenschaften abgefragt, anstatt pattern zu einem String zu casten.

Zum Beispiel wandelt String.prototype.endsWith() alle Eingaben in Strings um, würde aber werfen, wenn das Argument ein Regex ist, weil es nur zum Abgleich von Strings entworfen ist und die Verwendung eines Regex wahrscheinlich ein Entwicklerfehler ist.

Sie können die Prüfung umgehen, indem Sie [Symbol.match] auf einen falsy Wert setzen, der nicht undefined ist. Das würde bedeuten, dass der Regex nicht für String.prototype.match() verwendet werden kann (denn ohne [Symbol.match] würde match() ein neues RegExp-Objekt mit den beiden umschließenden Schrägstrichen konstruieren, die durch re.toString() hinzugefügt werden), aber für praktisch alles andere.

Perl-ähnliche RegExp-Eigenschaften

Beachten Sie, dass mehrere der RegExp-Eigenschaften sowohl lange als auch kurze (Perl-ähnliche) Namen besitzen. Beide Namen verweisen stets auf denselben Wert. (Perl ist die Programmiersprache, an der JavaScript seine regulären Ausdrücke orientiert hat.)

Parameter

Name Typ Default Beschreibung
$pattern Pflicht string | RegExp Der Text des regulären Ausdrucks oder, ab ES5, ein anderes RegExp-Objekt. Muster können auch Sonderzeichen enthalten, um Zeichen zu treffen, die nicht buchstäblich sind.
$flags string Wenn angegeben, ist flags ein String mit Flags, die dem regulären Ausdruck hinzugefügt werden, z. B. g, i, m, s, u, y, d.

Rückgabewert

Typ
RegExp
Beschreibung
Ein neues RegExp-Objekt, das das angegebene Muster und die Flags enthält.

Beispiele

Literal-Notation und Konstruktor

const re = /ab+c/i; // literal notation
// OR
const re = new RegExp("ab+c", "i"); // constructor with string pattern as first argument
// OR
const re = new RegExp(/ab+c/, "i"); // constructor with regular expression literal as first argument

String-Escape-Regeln im Konstruktor

const re = /\w+/;
// OR
const re = new RegExp("\\w+");

endsWith wirft bei Regex

"foobar".endsWith({ toString: () => "bar" }); // true
"foobar".endsWith(/bar/); // TypeError: First argument to String.prototype.endsWith must not be a regular expression

Prüfung mit Symbol.match umgehen

const re = /bar/g;
re[Symbol.match] = false;
"/bar/g".endsWith(re); // true
re.exec("bar"); // [ 'bar', index: 0, input: 'bar', groups: undefined ]
"bar & bar".replace(re, "foo"); // 'foo & foo'

Regulären Ausdruck zum Ändern des Datenformats verwenden

const re = /(\w+)\s(\w+)/;
const str = "Maria Cruz";
const newStr = str.replace(re, "$2, $1");
console.log(newStr);
Cruz, Maria

Zeilen mit unterschiedlichen Zeilenenden splitten

const text = "Some text\nAnd some more\r\nAnd yet\nThis is the end";
const lines = text.split(/\r?\n/);
console.log(lines); // [ 'Some text', 'And some more', 'And yet', 'This is the end' ]

Regulären Ausdruck über mehrere Zeilen anwenden

const s = "Please yes\nmake my day!";

s.match(/yes.*day/);
// Returns null

s.match(/yes.*day/s);
// Returns ["yes\nmake my day"]

Regulären Ausdruck mit dem sticky-Flag verwenden

const str = "#foo#";
const regex = /foo/y;

regex.lastIndex = 1;
regex.test(str); // true
regex.lastIndex = 5;
regex.test(str); // false (lastIndex is taken into account with sticky flag)
regex.lastIndex; // 0 (reset after match failure)

Unterschied zwischen sticky- und global-Flag

const re = /\d/y;
let r;
while ((r = re.exec("123 456"))) {
  console.log(r, "AND re.lastIndex", re.lastIndex);
}

// [ '1', index: 0, input: '123 456', groups: undefined ] AND re.lastIndex 1
// [ '2', index: 1, input: '123 456', groups: undefined ] AND re.lastIndex 2
// [ '3', index: 2, input: '123 456', groups: undefined ] AND re.lastIndex 3
//  … and no more match.

Regulärer Ausdruck und Unicode-Zeichen

const text = "Образец text на русском языке";
const regex = /[\u0400-\u04ff]+/g;

const match = regex.exec(text);
console.log(match[0]); // 'Образец'
console.log(regex.lastIndex); // 7

const match2 = regex.exec(text);
console.log(match2[0]); // 'на' (did not log 'text')
console.log(regex.lastIndex); // 15

// and so on

Subdomain-Namen aus URL extrahieren

const url = "http://xxx.example.com";
console.log(/^https?:\/\/(.+?)\./.exec(url)[1]); // 'xxx'

Regulären Ausdruck aus dynamischen Eingaben erstellen

const breakfasts = ["bacon", "eggs", "oatmeal", "toast", "cereal"];
const order = "Let me get some bacon and eggs, please";

order.match(new RegExp(`\\b(${breakfasts.join("|")})\\b`, "g"));
// Returns ['bacon', 'eggs']

// Wichtig · Fallstricke

Statt reguläre Ausdrücke zum Parsen von URLs zu verwenden, ist es meist besser, den browsereigenen URL-Parser über die URL-API zu nutzen. – Ab Firefox 34 ist bei einer Capturing-Gruppe mit Quantifikatoren, die ihre Anwendung verhindern, der gematchte Text für die Gruppe nun undefined statt eines leeren Strings. Aus Gründen der Web-Kompatibilität gibt RegExp.$N weiterhin einen leeren String statt undefined zurück.