Interpretieren Sie Escape-Zeichen in einer Zeichenfolge in Anführungszeichen

8

Eine einfache Anführungszeichen Zeichenfolge:

%Vor%

Ich möchte die Zeichenfolge inerpretieren / verarbeiten, als wäre sie double-quoted . Mit anderen Worten möchte ich all die mögliche Escape-Zeichen (nicht nur Tab und Linefeed wie in diesem Beispiel) mit den echten Werten, unter Berücksichtigung, dass der Backslash ebenfalls maskiert werden kann, also '\\ n 'muss durch' \ n 'ersetzt werden. eval () würde leicht tun, was ich brauche, aber ich kann es nicht verwenden.

Gibt es eine einfache Lösung?

(A ähnlicher Thread , das ich fand, befasst sich mit der Erweiterung von Variablen in der Zeichenfolge in Anführungszeichen, während ich nach dem Ersetzen von Escape-Zeichen bin.)

    
tmt 29.11.2011, 11:09
quelle

3 Antworten

5

Es gibt eine sehr einfache Möglichkeit, dies zu tun, basierend auf preg_replace Doc und stripcslashes , beide enthalten:

%Vor%

Dies funktioniert so lange wie "\n" "\n" und ähnliches werden soll. Demo .

Wenn Sie diese Zeichenfolgen wörtlich verarbeiten möchten, lesen Sie meine vorherige Antwort .

Bearbeiten: Sie haben in einem Kommentar gefragt:

  

Ich bin nur ein wenig verwirrt, was ist der Unterschied zwischen der Ausgabe von diesem und stripcslashes () direkt [?]

Der Unterschied ist nicht immer sichtbar, aber es gibt einen: stripcslashes löscht den \ -Zeichen, wenn keine Escape-Sequenz folgt. In PHP-Strings wird der Schrägstrich in diesem Fall nicht gelöscht. Ein Beispiel, "\d" , d ist kein Sonderzeichen, daher behält PHP den Schrägstrich:

%Vor%

Deshalb ist preg_replace hier nützlich, es wird nur die Funktion auf jene Teilstrings anwenden, wo stripcslashes wie vorgesehen funktioniert: alle gültigen Escape-Sequenzen.

    
hakre 29.11.2011, 16:50
quelle
5

Wenn Sie die genauen Escape-Sequenzen wie PHP machen müssen, benötigen Sie die lange Version, die die DoubleQuoted -Klasse ist. Ich habe die Eingabestring ein wenig erweitert, um mehr Escape-Sequenzen als in Ihrer Frage abzudecken, um dies generischer zu machen:

%Vor%

Ausgabe:

%Vor%

Wenn Sie jedoch gut daran sind, sich näher damit zu befassen, gibt es eine PHP-Funktion namens stripcslashes , zum Vergleich: I habe das Ergebnis davon und die PHP-Anführungszeichenfolge hinzugefügt:

%Vor%

Ausgabe:

%Vor%

Wie Sie sehen können, löscht stripcslashes hier einige Zeichen im Vergleich zur nativen Ausgabe von PHP.

( Bearbeiten: Siehe auch meine andere Antwort , die etwas Einfaches und Süßes bietet cstripslashes und preg_replace .)

Wenn stripcslashes nicht geeignet ist, gibt es DoubleQuoted . Sein Konstruktor nimmt eine Zeichenkette, die wie eine doppelt zitierte Zeichenkette behandelt wird (abzüglich Variablensubstitution, nur die Zeichen-Escape-Sequenzen).

Wie im Handbuch beschrieben, gibt es mehrere Escape-Sequenzen. Sie sehen aus wie reguläre Ausdrücke, und alle beginnen mit \ , also sieht es so aus, als würden sie in der Regel reguläre Ausdrücke verwenden.

Allerdings gibt es eine Ausnahme: \ überspringt die Escape-Sequenz. Der reguläre Ausdruck müsste Backtracking und / oder atomare Gruppen haben, um damit umgehen zu können, und ich spreche nicht fließend mit diesen, also habe ich nur einen einfachen Trick gemacht: Ich habe nur die regulären Ausdrücke auf die Teile der Zeichenkette angewendet, die% nicht enthalten. co_de%, indem Sie die Zeichenfolge zuerst explodieren und dann erneut implodieren.

Die zwei regulären Ausdrücke ersetzen Funktionen, \ Doc und preg_replace Doc , erlauben auch, auf Arrays zu operieren, das ist also ganz einfach zu tun.

Es ist in der Funktion preg_replace_callback Doc erledigt:

%Vor%

Siehe __toString() Doc und explode Doc Aufrufe. Diese sorgen dafür, dass implode nicht mit einem String arbeitet, der preg_replace_callback enthält. Daher wurde die Ersatzoperation von der Last befreit, mit diesen Sonderfällen fertig zu werden. Dies ist die Callback-Funktion, die von \ für jede Musterübereinstimmung aufgerufen wird. Ich habe es in einen Verschluss gehüllt, damit es nicht öffentlich zugänglich ist:

%Vor%

Sie benötigen einige zusätzliche Informationen, um es zu verstehen, da dies noch nicht die komplette Klasse ist. Ich gehe die fehlenden Punkte durch und füge den fehlenden Code hinzu:

Alle Muster, nach denen die Klasse "sucht", enthalten Untergruppen, mindestens eine. Dieser geht in preg_replace_callback und ist entweder das einzelne zu übersetzende Zeichen oder ein leerer String für Oktale und ein $type für hexadezimale Zahlen.

Die optionale zweite Gruppe x ist entweder nicht gesetzt ( $number ) oder enthält die oktale / hexadezimale Zahl. Der NULL -Eingabe wird auf die gerade benannten Variablen in dieser Zeile normalisiert:

%Vor%

Muster werden im Voraus als Sequenzen in einer privaten Membervariablen definiert:

%Vor%

Die Funktion $matches umschließt diese Definitionen nur in gültige reguläre PCRE-Ausdrücke wie:

%Vor%

Es ist ziemlich einfach:

%Vor%

Nun, da die Muster skizziert sind, erklärt dies, was getPatterns() enthält, wenn die Callback-Funktion aufgerufen wird.

Die andere Sache, die Sie wissen müssen, um zu verstehen, wie der Rückruf funktioniert, ist $matches . Das ist nur ein Array mit den einzelnen Ersatzzeichen:

%Vor%

Und das ist schon ziemlich viel für die Klasse. Es gibt eine weitere private Variable $map , die zum Speichern verwendet wird, wenn eine Ausnahme ausgelöst wurde, da $this->exception keine Ausnahmen auslösen kann und zu einem schwerwiegenden Fehler führen würde, wenn dies in der Callback-Funktion passieren würde. Also wird es gefangen und in einer privaten Klassenvariablen gespeichert, hier wieder der Teil des Codes:

%Vor%

Im Falle einer Ausnahme beim Ersetzen existiert die Funktion mit __toString() , was zu einer abfangbaren Ausnahme führt. Eine Getter-Funktion stellt die interne Ausnahme dann zur Verfügung:

%Vor%

Da es auch gut ist, auf die ursprüngliche Zeichenkette zuzugreifen, können Sie ein weiteres Getter hinzufügen, um das zu erhalten:

%Vor%

Und das ist die ganze Klasse. Hoffe, das ist hilfreich.

    
hakre 29.11.2011 13:55
quelle
0

Eine Regex-basierte Lösung wäre hier wahrscheinlich am besten zu pflegen (die Definitionen gültiger Escape-Sequenzen in Strings werden in der Dokumentation sogar als Regex bereitgestellt):

%Vor%

Das obige kann auch (und sollte wirklich) verbessert werden:

  • Packen Sie stattdessen die Ersetzungsfunktion als anonyme Funktion
  • Möglicherweise ersetzen Sie $map durch eine switch für eine kostenlose Leistungssteigerung
Jon 29.11.2011 11:55
quelle

Tags und Links