2015-08-11 10 views
18

Ich möchte alle URLs mit Unterstrichen auf ihre gestrichelten Äquivalent umleiten.Ausschließen von Verzeichnis von Regex-Weiterleitung

z. /nederland/amsterdam/car_rental wird /nederland/amsterdam/car-rental. Dazu benutze ich die hier beschriebene Technik: How to replace underscore to dash with Nginx. So ist mein Standort Block abgestimmt:

location ~ (_) 

Aber ich nur will dies auf URLs tun nicht im /admin Namespace. Um dies zu erreichen, habe ich versucht, die Regex mit einem negativen Lookup zu kombinieren: Regular expression to match a line that doesn't contain a word?. Die Lage passt jetzt mit:

(?=^(?!\/admin))(?=([^_]*)) 

Rubular berichtet die Zeichenfolge /nederland/amsterdam/car_rental die Regex übereinstimmen, während /admin/stats_dashboard nicht abgestimmt ist, so wie ich es will. Wenn ich diese Regel jedoch auf die nginx-Konfiguration anwende, endet die Site in Weiterleitungsschleifen. Gibt es etwas, was ich übersehen habe?

UPDATE: Ich möchte eigentlich nichts im Namespace /admin umschreiben. Das Unterstrich-zu-Strich-Neuschreiben sollte nur für alle URLs statt im Namespace /admin erfolgen.

Antwort

4
^(?!\/admin\b).* 

Sie müssen nur diese einfache regex mit lookahead .Siehe Demo.

https://regex101.com/r/uF4oY4/16

Ihre regex wird /nederland/amsterdam/car_rental scheitern, da es _ .So hat nur die Zeichenfolge /nederland/amsterdam/car berücksichtigt.

oder

können Sie

rewrite ^(?!\/admin\b)([^_]*)_(.*)$ $1-$2; 
+0

Dieser Beispielcode ist nicht effizient, weil Sie mehrere Male durch '$ uri' gehen müssen, um alle Unterstriche loszuwerden. – cnst

8

Verwendung Das Nginx location matching order so ist, dass Orte mit regulären Ausdrücken definiert werden in der Reihenfolge ihres Auftretens in der Konfigurationsdatei und die Suche nach regulären Ausdrücken überprüft auf die beendet erstes Spiel.

Mit diesem Wissen, in Ihren Schuhen, ich definiere einfach einen Ort mit einem regulären Ausdruck für "admin" über dem für die Unterstriche, die Sie von der Stack Overflow Answer erhalten haben, die Sie verknüpft haben.

location ~ (\badmin\b) { 
    # Config to process urls containing "admin" 
} 
location ~ (_) { 
    # Config to process urls containing "_" 
} 

Jede Anfrage mit admin in es wird nicht von dem ersten Stelle Block verarbeitet werden, ganz gleich, ob es einen Unterstrich oder nicht, weil der passenden Standort Block erscheint für die Unterstrichen davor hat.

** PS **

Als eine andere Antwort veröffentlicht von CNST ein paar Tage nach der Mine zeigt, der Link zu der Dokumentation auf der Position Matching, um I zeigt auch geschrieben, dass Sie auch die ^~ Modifikator verwenden können Ordnen Sie den Ordner /admin zu und überspringen Sie den Standortblock für die Unterstriche.

Ich persönlich tendiere dazu, diesen Modifikator nicht zu verwenden und regexbasierte Orte zusammen mit kommentierten Kommentaren zu verbinden, aber es ist sicherlich eine Option.

Allerdings müssen Sie je nach Konfiguration vorsichtig sein, da Anfragen, die mit "/ admin" beginnen, aber länger dauern, möglicherweise mit dem Modifizierer übereinstimmen und zu unerwarteten Ergebnissen führen.

Wie gesagt, ich bevorzuge meinen Regex-basierten Ansatz sicher in dem Wissen, dass niemand anfangen wird, die Reihenfolge der Dinge in der Konfigurationsdatei ohne ein klares Verständnis willkürlich zu ändern.

+2

Ich stimme zu, das ist ein besserer Ansatz als versuchen, nur einen Ausdruck zu verwenden. –

+0

Ich wollte das nur beantworten, aber du warst schneller. =) Upvoted. –

+0

String-Präfix-Matching (wie in der anderen Antwort) ist schneller als Regex passend — gibt es nichts in der Frage zu signalisieren, dass '/ admin' ist kein' $ uri' Präfix-String (eine solche Idee wurde stattdessen in der frühesten Antwort, dass freiwillig wurde seitdem gelöscht), als solche ist diese Antwort nicht optimal. Außerdem ist es ein sicherer Weg, um Heisenbugs in die Irre zu führen, wenn jemand sich dazu entschließt, den Code Monate oder Jahre neu zu arrangieren und dabei die Nuance der Reihenfolge des Standorts zu vergessen Direktiven spielen eine Rolle. – cnst

4

Sie haben nicht explizit auf die eine oder andere Weise erwähnt, aber es scheint, dass Sie wahrscheinlich nur einen einzigen /admin Namespace haben, der das Präfix $uri bildet und mit einem ^/admin.*$ Regex übereinstimmen würde; Lassen Sie mich auf dieser Grundlage zwei nicht kollidierende Konfigurationsoptionen bereitstellen.


Wie andere vorgeschlagen, sollten Sie eine separate location für /admin verwenden.

Doch anders als die andere Antwort, würde ich Ihnen raten, es mit einer Schnur Präfix, und verwenden Sie den ^~ Modifikator zu definieren nicht die reguläre Ausdrücke nach einem erfolgreichen Spiel zu überprüfen.

location ^~ /admin { 
} 

Alternativ oder auch zusätzlich für eine zusätzliche innere Ruhe und einen todsicheren Ansatz anstelle der Verwendung, was ein nicht-POSIX regulärer Ausdruck aus der verknüpften Antwort zu sein scheint (wenn meine Lektüre re_format(7) on OpenBSD ist zu glauben), betrachten Sie etwas, das viel einfacher ist, garantiert von den meisten Menschen verstanden werden, die behaupten, sie wissen, was REs sind, und arbeiten überall, um nicht zu sagen, wahrscheinlich effizienter sein, wenn man bedenkt, dass es das ist ^/admin.* Pfad, den Sie ausschließen möchten:

location ~ ^/[^a][^d][^m][^i][^n].*_.* { 
} 

Um Ihr Ziel zu erreichen, können Sie entweder eine dieser beiden Lösungen verwenden, oder sogar beide, um steifer und narrensicherer zu sein.

+0

Sie haben Recht mit dem einzelnen Namespace '/ admin'. Während Ihre Lösung gut aussieht, funktioniert sie nicht auf dem Pfad "/ amsterdam/test". Offenbar, weil es mit einem "a" beginnt. – richard

Verwandte Themen