ABAP REPLACE: Zeichenketten ersetzen – Mit und ohne Reguläre Ausdrücke

kategorie
ABAP-Statements
Veröffentlicht
autor
Johannes

Die REPLACE-Anweisung in ABAP wird verwendet, um Vorkommen eines Suchmusters (entweder eine feste Zeichenkette/Substring oder ein Muster, das durch einen Regulären Ausdruck definiert wird) innerhalb eines zeichenartigen Datenobjekts (z. B. STRING, C, N, D, T) zu finden und durch eine andere Zeichenkette zu ersetzen.

Ein wichtiger Aspekt ist, dass REPLACE die Variable, in der ersetzt wird, direkt modifiziert (Änderung “in place”).

Syntax

REPLACE [{FIRST OCCURRENCE}|{ALL OCCURRENCES OF}] " Was ersetzen? (Erstes oder Alle)
{<substring>}|{REGEX <regex>} " Wonach suchen? (Text oder Regex)
IN <variable> " Wo suchen/ersetzen? (Wird verändert!)
WITH <ersatz> " Womit ersetzen?
[<optionen>]. " Weitere Optionen
  • FIRST OCCURRENCE: Ersetzt nur das erste gefundene Vorkommen des Suchmusters.
  • ALL OCCURRENCES OF (Standard, wenn FIRST OCCURRENCE fehlt): Ersetzt alle nicht-überlappenden Vorkommen des Suchmusters.
  • <substring>: Der exakte Text (Literal oder Variable), nach dem gesucht werden soll.
  • REGEX <regex>: Ein Regulärer Ausdruck (Literal oder Variable, PCRE-Syntax), der das zu suchende Muster beschreibt. Dies ermöglicht flexible Mustersuche.
  • IN <variable>: Die zeichenartige Variable, deren Inhalt durchsucht und modifiziert wird. Achtung: Der Inhalt dieser Variable wird direkt geändert!
  • WITH <ersatz>: Die Zeichenkette (Literal oder Variable), die anstelle der gefundenen Suchmuster eingefügt wird.
  • <optionen>: (Auswahl)
    • IGNORING CASE / RESPECTING CASE (Standard): Steuert, ob bei der Suche die Groß-/Kleinschreibung beachtet wird.
    • REPLACEMENT COUNT <anz>: Speichert die Anzahl der durchgeführten Ersetzungen in die Variable <anz> (Typ I).
    • REPLACEMENT OFFSET <off>: Speichert den Offset der Position nach der letzten Ersetzung in <off>.
    • REPLACEMENT LENGTH <len>: Speichert die Länge des zuletzt eingefügten Ersatz-Strings in <len>.
    • RESULTS <results>: Ermöglicht das Speichern detaillierter Informationen über jede Ersetzung (Position, Länge etc.) in einer Struktur oder internen Tabelle (ähnlich wie bei FIND).
    • IN SECTION OFFSET <sec_off> LENGTH <sec_len> OF: Beschränkt die Suche und Ersetzung auf einen Teilbereich der <variable>.

Spezielle Zeichen im Ersatz (<ersatz>) bei `REGEX

Wenn REGEX verwendet wird, können im <ersatz>-String spezielle Platzhalter genutzt werden:

  • $0 oder $&: Steht für den gesamten vom Regex gefundenen Textabschnitt.
  • $1, $2, $3…: Steht für den Text, der von der ersten, zweiten, dritten… geklammerten Gruppe (Capture Group) im Regulären Ausdruck erfasst wurde.
  • ` (Backtick): Steht für den Teil der <variable> vor dem gefundenen Textabschnitt.
  • $': Steht für den Teil der <variable> nach dem gefundenen Textabschnitt.
  • $$: Stellt ein literales Dollarzeichen ($) im Ersatztext dar.

Verhalten bei fester Länge (Typ C)

Wenn <variable> vom Typ C (feste Länge) ist:

  • Ist der <ersatz> kürzer als der gefundene Text, wird der Rest des ursprünglichen Platzes rechts mit Leerzeichen aufgefüllt.
  • Ist der <ersatz> länger als der gefundene Text und würde das Ergebnis die definierte Länge der Variablen überschreiten, wird das Ergebnis rechts abgeschnitten. Datenverlust ist möglich!
  • Empfehlung: Für Ersetzungen, bei denen sich die Länge stark ändern kann, ist die Verwendung einer Zielvariablen vom Typ STRING sicherer.

Systemfelder

  • sy-subrc:
    • 0: Es wurde mindestens eine Ersetzung durchgeführt.
    • 4: Das Suchmuster wurde nicht gefunden, es fand keine Ersetzung statt.
  • sy-fdpos: Enthält den Offset der Position nach dem zuletzt ersetzten bzw. eingefügten Text.

Moderne Alternativen

Besonders für STRING-Variablen bietet das moderne ABAP oft Alternativen, die manchmal lesbarer sind oder die Originalvariable nicht verändern:

  • Funktion replace(...): Gibt einen neuen String zurück, in dem Ersetzungen vorgenommen wurden.
    DATA(new_string) = replace( val = old_string sub = 'alt' with = 'neu' occ = 0 ). " occ=0 -> alle
  • String-Templates (|...|): Können für komplexere Neuaufbauten von Strings genutzt werden.

REPLACE bleibt jedoch ein mächtiges Werkzeug, vor allem durch die REGEX-Option.

Beispiele

1. Erstes Vorkommen ersetzen

DATA text1 TYPE string VALUE 'Test: Apfel, Birne, Apfel'.
REPLACE FIRST OCCURRENCE OF 'Apfel' IN text1 WITH 'Orange'.
WRITE: / text1. " Ausgabe: Test: Orange, Birne, Apfel

2. Alle Vorkommen ersetzen (Case-Insensitiv)

DATA text2 TYPE string VALUE 'Fehler: ERROR Code 1, Error Code 2'.
REPLACE ALL OCCURRENCES OF 'error' IN text2 WITH 'WARNUNG' IGNORING CASE.
WRITE: / text2. " Ausgabe: Fehler: WARNUNG Code 1, WARNUNG Code 2

3. Anzahl der Ersetzungen zählen

DATA text3 TYPE string VALUE 'a b c a b c a'.
DATA count TYPE i.
REPLACE ALL OCCURRENCES OF 'a' IN text3 WITH 'X' REPLACEMENT COUNT count.
WRITE: / text3. " Ausgabe: X b c X b c X
WRITE: / 'Anzahl Ersetzungen:', count. " Ausgabe: 3

4. Ersetzen mit Regulärem Ausdruck (Mehrfache Leerzeichen -> 1 Leerzeichen)

DATA text4 TYPE string VALUE 'Wort1 Wort2 Wort3 Wort4'.
REPLACE ALL OCCURRENCES OF REGEX `\s{2,}` IN text4 WITH ` `. " \s{2,} = 2 oder mehr Leerzeichen
WRITE: / text4. " Ausgabe: Wort1 Wort2 Wort3 Wort4

5. Regex mit Capture Groups (Datum umformatieren YYYYMMDD -> DD.MM.YYYY)

DATA date_in TYPE string VALUE '20250421'.
REPLACE REGEX `(\d{4})(\d{2})(\d{2})` IN date_in WITH '$3.$2.$1'. " $1=YYYY, $2=MM, $3=DD
WRITE: / date_in. " Ausgabe: 21.04.2025

6. Typ C und Abschneiden

DATA text_c TYPE c LENGTH 15 VALUE 'Kurzer Text'.
WRITE: / 'Vorher :', |'{ text_c }'|.
REPLACE 'Text' IN text_c WITH 'längerer Inhalt'. " Ersatz ist viel länger
WRITE: / 'Nachher:', |'{ text_c }'|.

Ausgabe:

Vorher : '{Kurzer Text }'
Nachher: '{Kurzer längerer}'

(Der Ersatz “längerer Inhalt” wurde nach “längerer” abgeschnitten, um die Feldlänge 15 einzuhalten).

Wichtige Hinweise / Best Practice

  • Denken Sie daran, dass REPLACE die Variable direkt verändert. Machen Sie ggf. vorher eine Kopie.
  • Seien Sie vorsichtig mit REPLACE bei Feldern fester Länge (Typ C), da es zu Datenverlust durch Abschneiden kommen kann. Verwenden Sie hierfür bevorzugt STRING.
  • Nutzen Sie die REGEX-Option für flexible und mächtige Musterersetzungen.
  • Prüfen Sie sy-subrc nach der Anweisung, um festzustellen, ob Ersetzungen stattgefunden haben.
  • Betrachten Sie die Funktion replace(...) und String-Templates als moderne Alternativen, besonders wenn der Originalwert erhalten bleiben soll.