Regex für den Routenabgleich in Express

75

Ich bin nicht sehr gut mit regulären Ausdrücken, deshalb möchte ich sicherstellen, dass ich das richtig mache. Nehmen wir an, ich habe zwei sehr ähnliche Routen /discussion/:slug/und /page/:slug/. Ich möchte eine Route erstellen, die diesen beiden Seiten entspricht.

app.get('/[discussion|page]/:slug', function(req, res, next) {
  ...enter code here...
})

Ist das der richtige Weg? Im Moment erstelle ich nur zwei separate Routen.

someFunction = function(req, res, next) {..}
app.get('/discussion/:slug', someFunction)
app.get('/page/:slug', someFunction)
Jonathan Ong
quelle
4
Sind Sie zuversichtlich, dass die []Klammern abwechselnd verwendet werden? Das wäre das erste Mal, dass ich sie so gesehen habe. (Parens ()sind häufiger in mehr Werkzeugen - ich kenne Ihr spezifisches Werkzeug einfach nicht.)
Sarnold
1
whoops, Tippfehler. Aber ich versuche Beispiele für Express zu finden und kann keine finden (oder ich kenne die zu suchenden Begriffe nicht).
Jonathan Ong
Machen Sie 'someFunction' genau zur gleichen Funktion. Dies ist viel einfacher. Vielleicht haben Sie dies bereits getan
Alexander Mills
In einem solchen Fall ist auch app.get (['/ diskussion /: slug', / page /: slug '], Funktion (req, res, next) {... Code hier eingeben ...}) eine Option.
Max

Antworten:

119

app.get('/:type(discussion|page)/:id', ...) funktioniert

Jonathan Ong
quelle
7
Ich denke, der entscheidende Punkt dabei ist, dass Sie den Anforderungsparameter der Regex zuweisen können, indem Sie ihn in "()" nach dem Parameternamen setzen. IE: :type(<regex>)wird req.params.typeauf die übereinstimmende Zeichenfolge gesetzt. Sie können die Regex nicht vor die Variable setzen.
Dualität
2
Diese Syntax sieht gut aus, scheint aber überhaupt nicht unter expressjs.com/en/guide/routing.html dokumentiert zu sein :-(
rjmunro
7
@rjmunro Es ist in dem path-to-regexpModul dokumentiert , das Express verwendet. (Dies wird in den Express-Dokumenten erwähnt, ist aber leicht zu übersehen.) Siehe github.com/pillarjs/path-to-regexp
broofa
Danke, es funktioniert bei mir. Es scheint case sensitivejedoch falsestandardmäßig eingestellt zu sein . Kann ich es auf true setzen? Dies scheint der offizielle Weg
bcjohn
67

Sie sollten ein wörtliches Javascript-Objekt mit regulärem Ausdruck verwenden, keine Zeichenfolge, und @sarnold ist richtig, dass Sie Parens für den Wechsel wünschen. Eckige Klammern stehen für Zeichenklassen.

const express = require("express");
const app = express.createServer();
app.get(/^\/(discussion|page)\/(.+)/, function (req, res, next) {
  res.write(req.params[0]); //This has "discussion" or "page"
  res.write(req.params[1]); //This has the slug
  res.end();
});

app.listen(9060);

Das (.+)bedeutet, dass ein Slug mit mindestens 1 Zeichen vorhanden sein muss, sonst stimmt diese Route nicht überein. Verwenden (.*)Sie diese Option, wenn Sie möchten, dass sie auch zu einer leeren Schnecke passt.

Peter Lyons
quelle
Gibt es eine Möglichkeit, dies ohne Regex und als Zeichenfolge zu verwenden? Ich bevorzuge Schlüsselwortparameter anstelle einer Liste.
Jonathan Ong
1
AFAIK Es gibt keine Möglichkeit, eine Zeichenfolge mit benannten Parametern zu verwenden, wenn Sie die ausgeklügelten Übereinstimmungsfähigkeiten regulärer Ausdrücke benötigen. TJ sagt dies in der Expressdokumentation. Ich glaube, es ist letztendlich eine Einschränkung von Javascript-Objekten mit regulären Ausdrücken.
Peter Lyons
3
Sie können dies tunapp.get(new RegExp('(your|string)\/here'), function…
Misha Reyzlin
5
Ihr regulärer Ausdruck ist am Anfang der URL nicht verankert. Drückt explizit Anker aus oder sollte der reguläre Ausdruck / \ / sein (Diskussion | pa ...
user239558
1
Es sollte /^\/(discussion|page)\/(.+)/wie vom Benutzer oben vorgeschlagen sein. Ich habe eine Bearbeitung vorgeschlagen.