PHP Regex und angrenzende Erfassungsgruppen

8

Ich verwende Capture-Gruppen in regulären Ausdrücken zum ersten Mal und ich frage mich, was mein Problem ist, da ich davon ausgehe, dass die Regex-Engine die Zeichenfolge von links nach rechts durchsucht.

Ich versuche, eine UpperCamelCase-Zeichenfolge in eine hyphened-Kleinbuchstaben-Zeichenfolge umzuwandeln, also zum Beispiel:

%Vor%

Meine Voraussetzung ist eine alphabetische Zeichenfolge, sodass ich mich nicht um Zahlen oder andere Zeichen kümmern muss. Hier ist, was ich versucht habe:

%Vor%

Das Ergebnis:

%Vor%

Das ist fast das, was ich möchte, außer dass zwischen a und test ein Bindestrich stehen sollte. Ich habe A-Z bereits in meine erste Capturing-Gruppe aufgenommen, also würde ich annehmen, dass die Engine AT sieht und diese Bindestriche trennt.

Was mache ich falsch?

    
rink.attendant.6 23.06.2014, 06:43
quelle

3 Antworten

6

Der Grund, warum Ihre Regex nicht funktioniert: Überlappende Übereinstimmungen

  • Ihre Regex stimmt mit sA in IsATest überein, sodass Sie - zwischen s und A einfügen können.
  • Um eine - zwischen A und T einzufügen, müsste die Regex mit AT übereinstimmen.
  • Dies ist unmöglich, weil A bereits als Teil von sA übereinstimmt. Sie können keine überlappenden Übereinstimmungen in der direkten Regex haben.
  • Verliert die Hoffnung? Nein! Dies ist eine perfekte Situation für einen Blick.

Mach es in zwei einfachen Zeilen

Hier ist der einfache Weg, es mit Regex zu tun:

%Vor%

Sehen Sie sich die Ausgabe am Ende der php-Demo an:

  

Ausgabe: hello-world-this-is-a-test

Wird in einem Moment eine Erklärung hinzufügen. :)

  • Die Regex passt zu keinen Zeichen. Es zielt vielmehr auf Positionen in der Zeichenfolge ab: die Positionen zwischen der Änderung im Groß- und Kleinbuchstaben. Um dies zu tun, verwendet es einen Lookbehind und einen Lookahead
  • Das (?<=[a-zA-Z]) lookbehind behauptet, dass vor der aktuellen Position ein Buchstabe
  • steht
  • Das (?=[A-Z]) lookahead behauptet, dass der aktuellen Position ein Großbuchstabe folgt.
  • Wir ersetzen nur diese Positionen durch - und konvertieren das Los in Kleinbuchstaben.

Wenn Sie sich diesen Bildschirm von regex101 genau ansehen, können Sie Zeilen zwischen den Wörtern sehen, in denen die Regex übereinstimmt.

>

Referenz

zx81 23.06.2014, 06:52
quelle
5

Ich habe die zwei regulären Ausdrücke der Einfachheit halber getrennt:

%Vor%

Er verarbeitet die Zeichenfolge zweimal, um Folgendes zu finden:

  1. Kleinbuchstaben - & gt; Großbuchstaben
  2. mehrere Großbuchstaben gefolgt von einem anderen Großbuchstaben

Dies wird das folgende Verhalten haben:

%Vor%

Alternativ können Sie eine Look-Ahead-Assertion verwenden (dies bewirkt die Wiederverwendung des letzten Großbuchstabens, der im vorherigen Match verwendet wurde):

%Vor%     
Ja͢ck 23.06.2014 07:15
quelle
4

Um den interessanten Anwendungsfall zu beheben, den Jack in Ihren Kommentaren erwähnt hat (Vermeiden Sie das Aufspalten von Abkürzungen), ging ich mit dem Weg von zx81, Lookahead und Lookbehinds zu verwenden.

%Vor%

Sie können es zur Erklärung in zwei Teile aufteilen:

Erster Teil

%Vor%

(TL; DR: Übereinstimmung zwischen Strings des CamelCase Patterns.)

Zweiter Teil

%Vor%

(TL; DR: Sonderfall, Übereinstimmung zwischen Abkürzung und CamelCase-Muster)

Also wäre Ihr Code dann:

%Vor%

Demo der Übereinstimmungen

Demo des Codes

    
ohaal 23.06.2014 06:48
quelle