Ansicht
Dokumentation

ABENREGEX_POSIX_PCRE_INCOMPAT - REGEX POSIX PCRE INCOMPAT

ABENREGEX_POSIX_PCRE_INCOMPAT - REGEX POSIX PCRE INCOMPAT

ROGBILLS - Synchronize billing plans   CL_GUI_FRONTEND_SERVICES - Frontend Services  
Diese Dokumentation steht unter dem Copyright der SAP AG.
SAP E-Book

- Inkompatibilitäten zwischen POSIX und PCRE

Dieser Abschnitt listet alle Funktionen der regulären POSIX-Ausdrücke auf, die nicht direkt in PCRE wiederverwendet werden können, aber etwas Migrationsaufwand erfordern, indem die regulären Ausdrücke neu geschrieben werden.

Migrationsmuster

Im Wesentlichen bilden die von PCRE unterstützten Funktionen eine Obermenge der von POSIX unterstützten Funktionen. Dennoch gibt es einige grundlegende Unterschiede und fehlende Funktionen, die in den folgenden Abschnitten beschrieben werden.

Grundlegende Unterschiede

Sowohl PCRE als auch POSIX verwenden einen regex-gerichteten Backtracking-Algorithmus, sodass beide Implementierungen in den meisten Fällen das gleiche Ergebnis liefern. Dennoch gibt es einen wichtigen Unterschied: PCRE wird immer die erste Übereinstimmung ganz links liefern, während POSIX darauf abzielt, die längste Übereinstimmung ganz links zu liefern. Das heißt, wenn mehrere mögliche Übereinstimmungen am selben Offset beginnen, wird die längste davon zurückgegeben.

Wenn sie von der „leftmost longest“-Abgleichsregel in POSIX Gebrauch machen, müssen Sie möglicherweise Teile Ihres regulären Ausdrucks neu anordnen oder schreiben, um dieselben Ergebnisse wie in PCRE zu erzielen.

PCRE stoppt, nachdem die erste Übereinstimmung (ganz links) gefunden wurde, während POSIX auch die andere Übereinstimmung, die an der gleichen Position beginnt, probiert und sie als bessere Übereinstimmung betrachtet, da sie länger ist.

Um auch im PCRE-Fall die längste Übereinstimmung zurückzugeben, kann das Beispiel oben durch die Neuanordnung der Alternationen wie folgt umgeschrieben werden:

Die unterschiedlichen Abgleichstrategien wirken sich jedoch nicht nur auf die Alternationen aus, die durch | eingeleitet werden, sondern auf alle Fälle, in denen mehrfache Übereinstimmungen an der gleichen Stelle beginnen, z.B. mit dem Quantor ?:

Mit einer „vorausschauenden Zusicherung“ kann dann auch die längste Übereinstimmung im PCRE-Fall zurückgegeben werden:

Bedeutung von Leerräumen im Mustern

Die PCRE-Syntax ist standardmäßig in einem erweiterten Modus auf AS ABAP kompiliert: Die meisten nicht maskierten Leerräume (Leerzeichen und Zeilenumbrüche) im Muster werden außerhalb von Zeichenklassen ignoriert. Um Leerräume in ein Muster einzubinden, müssen sie maskiert werden. Für den expliziten Abgleich von Leerräumen im erweiterten Modus von PCRE gibt es die folgenden Optionen:

  • Leerraum im Muster maskieren. Das Muster Hello\ World stimmt mit Hello World überein.
  • Alle Leerräume mit dem Sonderzeichen \s abgleichen. Hello\sWorld stimmt mit Hello World überein. Dasselbe gilt für Hello \s World, was gegebenenfalls lesbarer ist.

Der erweiterte Modus ermöglicht zwar das Schreiben lesbarerer regulärer Ausdrücke, jedoch kann es am Anfang etwas unübersichtlich sein, insbesondere bei der Migration von regulären POSIX-Ausdrücken. Der erweiterte Modus von PCRE kann wie folgt ausgeschaltet werden:

  • Durch Übergabe von ABAP_FALSE an den Parameter EXTENDED beim Anlegen eines regulären PCRE-Ausdrucks mit Methode CREATE_PCRE der Klasse CL_ABAP_REGEX.
  • Durch Verwendung des Sonderzeichens (?-x) im Muster selbst. Das funktioniert auch für den Zusatz PCRE in Anweisungen und den Parameter pcre in Zeichenkettenfunktionen.

Der erweiterte Modus für PCRE wird bei der Verwendung von Parameter pcre in der folgenden Funktion aktiviert. Das heißt, dass Leerzeichen bei der Auswertung des Musters als irrelevant behandelt werden. Der reguläre PCRE-Ausdruck stimmt nicht mit der Zeichenkette Hello World überein.

Dennoch wird die Zeichenkette HelloWorld von PCRE, aber nicht von POSIX abgeglichen:

Das folgende Beispiel zeigt schließlich, wie der erweiterte Modus in eingebauten Zeichenkettenfunktionen ausgeschaltet werden kann:

Anmerkungen

Im erweiterten Modus von PCRE können Kommentare hinter ein nicht maskiertes #-Zeichen gestellt werden. Um das #-Zeichen in ein Muster im erweiterten Modus von PCRE einzubinden, muss es maskiert werden:

Das Muster Hello\#World stimmt mit Hello#World überein.

Der erweiterte Modus von PCRE kann wie im vorherigen Abschnitt beschrieben ausgeschaltet werden:

Der erweiterte Modus für PCRE wird bei der Verwendung von Parameter pcre in der folgenden Funktion aktiviert. Das heißt, dass das #-Zeichen ein Kommentar einleitet. Der erste reguläre PCRE-Ausdruck stimmt nicht mit der Zeichenkette Hello#World überein. Ein regulärer POSIX-Ausdruck und der zweite und dritte reguläre PCRE-Ausdruck, in denen # maskiert oder der erweiterte Modus ausgeschaltet ist, stimmen mit der Zeichenkette überein.

Unicode-Behandlung

Für die Darstellung von Zeichenketten unterstützt die ABAP-Programmiersprache die 2-Byte- Unicode-Zeichendarstellung USC-2. Die System-Codepage eines AS ABAP ist UTF-16 und unterstützt alle Zeichen des Unicode-Standards. UCS-2 ist eine Teilmenge von UTF-16 und unterstützt die sogenannte Basic Multilingual Plane (BMP) des Unicode-Standards. In UTF-16 werden die anderen Unicode-Planes als Surrogate( Surrogatpaare) im Surrogat-Bereich kodiert.

Reguläre POSIX-Ausdrücke nehmen immer UCS-2 an und behandeln Zeichen, die von Surrogatpaaren dargestellt werden, als zwei einzelne Zeichen. Das kann zu unerwarteten Ergebnissen führen. Im Gegensatz zu POSIX kann PCRE Zeichenketten als UCS-2 oder als UTF-16 behandeln. Das kann auf verschiedene Weisen in Abhängigkeit vom Typ der ausgeführten regulären Ausdrucksoperation konfiguriert werden:

Operation Beschreibung Standardverhalten:
Methode der Systemklassen CL_ABAP_REGEX und CL_ABAP_MATCHER Die Unicode-Behandlung wird vom Parameter UNICODE_HANDLING der Factory-Behandlung CREATE_PCRE gesteuert. Die folgenden Werte können übergeben werden: \lbr \lbr STRICT - behandeln Zeichenkette als UTF-16, lösen bei Erreichen einer ungültigen UTF-16-Kodierung (korrupte Surrogatpaare) eine Ausnahme aus \lbr \lbr IGNORE - behandeln Zeichenketten als UTF-16, ignorieren ungültige UTF-16-Kodierungen; die Teile der Eingabe, die keine gültige UTF-16-Kodierung sind, können auf keine Weise abgeglichen werden \lbr \lbrRELAXED - behandeln Zeichenkette als UCS-2; Sonderzeichen \C ist in Mustern aktiviert, der Abgleich von Surrogatpaaren nach deren Unicode-Codepunkt ist jedoch nicht mehr möglich STRICT
Zusatz PCRE der Anweisungen FIND und REPLACE, \lbr \lbrArgument pcre der eingebauten Funktionen für Zeichenketten Es gibt keinen Zusatz zur Steuerung der Unicode-Behandlung. Stattdessen kann die Syntax (*UTF) am Anfang des Musters angegeben werden, um den strikten Modus einzuschalten (siehe oben) Ohne (*UTF) wird der laxe Modus (siehe oben) verwendet, jedoch kann das Sonderzeichen \C nicht verwendet werden

Die folgende Tabelle bietet einen kurzen Überblick darüber, welcher Unicode-Modus bei der Migration eines Musters aus POSIX zu PCRE verwendet werden soll:

Operation Eingabe als UCS-2 oder als UTF-16 behandeln? Ungültige UTF-16-Kodierung akzeptieren? Aktion
Methode der Systemklassen CL_ABAP_REGEX und CL_ABAP_MATCHER UTF-16 Ja UNICODE_HANDLING auf IGNORE setzen
Methode der Systemklassen CL_ABAP_REGEX und CL_ABAP_MATCHER UTF-16 Nein UNICODE_HANDLING auf STRICT setzen (Standard)
Methode der Systemklassen CL_ABAP_REGEX und CL_ABAP_MATCHER UCS-2 (ABAP-Standard) - UNICODE_HANDLING auf RELAXED setzen
Anweisungen und eingebaute Funktionen UTF-16 Ja Das kann nicht mit dem Zusatz PCRE von Anweisungen und dem Argument pcre von eingebauten Funktionen erreicht werden; Objekte von CL_ABAP_REGEX verwenden
Anweisungen und eingebaute Funktionen UTF-16 Nein Syntax (*UTF) zum Muster hinzufügen
Anweisungen und eingebaute Funktionen UCS-2 (ABAP-Standard) - Keine Aktion erforderlich, laxer Modus ist Standard

Beispiel

Das Sonderzeichen . stimmt mit zwei UCS-2-Zeichen in den ersten zwei Ersetzungen überein, obwohl sie ein Surrogatpaar für ein einzelnes UTF-16-Zeichen bilden. Die dritte Ersetzung verwendet (*UTF) am Anfang eines regulären PCRE-Ausdrucks und nur das UTF-16-Zeichen wird abgeglichen und ersetzt.

Abgleich von Groß- und Kleinbuchstaben

Die POSIX-Syntax \u und \l zum Abgleich von jeweils einem Großbuchstaben und einem Kleinbuchstaben wird von PCRE nicht direkt unterstützt. Das beinhaltet die entsprechenden Negationen \U und \L.

Alternativ kann die Syntax \p{xx} und \P{xx} von PCRE verwendet werden, um Zeichen abzugleichen, die bestimmte Unicode-Zeicheneigenschaften haben:

Beschreibung POSIX-Syntax PCRE-Syntax
Großbuchstabe \u \p{Lu}
kein Großbuchstabe \U \P{Lu}
Kleinbuchstabe \l \p{Ll}
kein Kleinbuchstabe \L \P{Ll}

Die folgenden Ersetzungen liefern das gleiche Ergebnis.

Abgleich von allen Unicode-Zeichen

Obwohl PCRE die meisten benannten Mengen, die in der POSIX-Syntax verfügbar sind, unterstützt, gibt es eine Ausnahme: Die Menge [[:unicode:]], die mit einem beliebigem Zeichen, dessen Code größer als 255 ist, übereinstimmt.

Je nach Kontext gibt es verschiedene Möglichkeiten, um das gleiche Verhalten in PCRE zu erreichen:

POSIX-Syntax PCRE-Syntax Beschreibung
[[:unicode:]] [^\x{00}-\x{ff}] ein eigenständiger [[:unicode:]] kann durch die Negierung des Bereichs der Zeichen von 0x00 bis 0xff ersetzt werden
[^[:unicode:]] [\x{00}-\x{ff}] ähnlich kann ein eigenständiger [[:unicode:]] durch den Bereich der Zeichen von 0x00 bis 0xff ersetzt werden
[[:unicode:]...] [\x{100-\xffff}...] Wenn [[:unicode:]] in Kombination mit anderen Elementen in einer Zeichenklasse verwendet wird, muss der Zeichenbereich explizit angegeben werden (nicht durch Negierung); wenn der reguläre Ausdruck in einem Nicht-UTF-16-Kontext ausgeführt werden soll ( UNICODE_HANDLING ist auf RELAXED gesetzt), ist es der Zeichenbereich von 0x100 bis 0xffff
[[:unicode:]...] [\x{100}-\x{10ffff}...] in einem UTF-16-Kontext (UNICODE_HANDLING ist auf STRICT oder IGNORE gesetzt) wird dieser Bereich 0x100 bis 0x10ffff
[^[:unicode:]...] [^\x{100}-\x{ffff}...] wenn [[:unicode:]] in Kombination mit anderen Elementen in einer negierten Zeichenklasse verwendet wird, muss der Bereich von 0x100 bis 0xffff für einen Nicht-UTF-16-Kontext explizit angegeben werden
[^[:unicode:]...] [^\x{100}-\x{10ffff}...] in einem UTF-16-Kontext wird dieser Bereich 0x100 bis 0x10ffff

Wenn Sie nur den Zeichenbereich von 0 bis 27 oder dessen Negierung berücksichtigen möchten, können Sie die in PCRE verfügbare benannte POSIX-Menge [[:ascii:]] verwenden. Mit der negativen benannten POSIX-Mengensyntax ([[:^ascii:]]) von PCRE können Sie Nicht-ASCII-Zeichen abgleichen. Die negative benannte POSIX-Mengensyntax kann auch in negierten Zeichenklassen verwendet werden, wodurch viel Flexibilität ermöglicht wird.

Beispiel

Die folgenden Suchen liefern das gleiche Ergebnis.

Wortanker

Die POSIX-Syntax \< und \> zum Abgleich von jeweils dem Anfang und dem Ende eines Worts wird von PCRE nicht direkt unterstützt. Als Alternative kann der Wortanker \b, der mit dem Anfang und dem Ende eines Worts übereinstimmt, in Kombination mit einer vorausschauenden oder zurückblickenden Zusicherung verwendet werden. Ansonsten kann ein Sonderzeichensatz verwendet werden.

Beschreibung POSIX-Syntax PCRE-Syntax
Wortanfang \< \b(?=\w) oder [[:<:]]
Wortende \> \b(?<=\w) oder [[:>:]]

Die folgenden Ersetzungen liefern das gleiche Ergebnis.

Migration von Ersetzungszeichenfolgen

Abgesehen von den Verweis auf eine erfassende Gruppe über ihre Nummer ($1, $2, $3, ...) gibt es einen deutlichen Unterschied zwischen der Ersetzungszeichenfolgen-Syntax und den Möglichkeiten von PCRE und denen von POSIX.

Ersetzen der gesamten Übereinstimmung

POSIX bietet sowohl $0 als auch $& als Platzhalter für die gesamte Übereinstimmung in der Ersetzungszeichenfolge an. PCRE unterstützt nur die erste Syntax $0 und löst mit der Syntax $& eine Ausnahme aus. Wenn Sie die Syntax $& in Ihren POSIX-Mustern verwenden, können Sie sie bei der Migration zu PCRE einfach durch $0 ersetzen.

Die folgenden Ersetzungen liefern das gleiche Ergebnis.

Ersetzen von Teilen vor und nach der Übereinstimmung

POSIX unterstützt $` und $' als Platzhalten für den Text jeweils vor uder nach der Übereinstimmung. PCRE bietet keine äquivalente Funktion. Wenn Ihr Muster POSIX-Funktionen verwendet, können Sie aber versuchen, diese zu emulieren, z.B. durch die Einführung zusätzlicher erfassender Gruppen.

Bei diesem Ansatz gibt es jedoch Einschränkungen. Wenn Ihr Muster oder Ihre Ersetzungszeichenfolge komplexer ist, müssen Sie gegebenenfalls entweder die Ersetzung manuell durchführen (mithilfe von Zeichenkettenoperationen, dem Offset und der Länge aus der Übereinstimmung), oder Ihr POSIX-Muster mit dem Pragma ##regex_posix behalten.

Die folgenden Ersetzungen liefern das gleiche Ergebnis.






CL_GUI_FRONTEND_SERVICES - Frontend Services   RFUMSV00 - Advance Return for Tax on Sales/Purchases  
Diese Dokumentation steht unter dem Copyright der SAP AG.

Length: 27609 Date: 20240523 Time: 095209     sap01-206 ( 339 ms )