Reguläre Ausdrücke in ABAP – Regular Expressions

Reguläre Ausdrücke sind ein wichtiges Konzept in der Programmierung, und damit auch in der ABAP-Programmierung im SAP-System. Mithilfe von regulären Ausdrücken kannst Du einfach in Zeichenketten nach einem gewissen Muster suchen. Dadurch kannst Du Zeichenketten validieren und verändern. Mithilfe von wenigen Zeilen Code kannst Du effizient und einfach eine Suche durchführen. Eine Suche mit regulären Ausdrücken in ABAP ist leistungsfähiger als herkömmliche SAP-Muster.

In diesem Artikel erkläre ich Dir, was man unter regulären Ausdrücken im Allgemeinen versteht, wie Du sie vorab überprüfen kannst und wie Du in der Programmiersprache ABAP reguläre Ausdrücke verwenden kannst. Gerade für Einsteiger sind reguläre Ausdrücke komplex. Wenn Du sie aber verstehst, wirst Du den großen Funktionsumfang und Nutzen von regulären Ausdrücken schätzen.

Reguläre Ausdrücke – Definition

Reguläre Ausdrücke (auch RegEx genannt) sind Muster, die zum Abgleichen von Zeichenkombinationen in Zeichenketten verwendet werden. Ein regulärer Ausdruck besteht aus Buchstaben und Symbolen, die ein Suchmuster bilden.

Viele Programmiersprachen erlauben es Entwicklern, reguläre Ausdrücke zu definieren und sie dann zu verwenden. Typische Anwendungsfälle sind folgende:

  • Text nach bestimmten Muster überprüfen
  • Teile eines Textes finden
  • Teile eines Textes extrahieren
  • Text durch anderen Text ersetzen

In regulären Ausdrücken können Metazeichen verwendet werden. Dabei handelt es sich um Symbole, die für die Suche keine wörtliche Bedeutung haben, aber zur Definition des Suchmusters verwendet werden. Das Sternchen (*) z.B. kann für beliebige Zeichen stehen.

Anwendungsfälle von regulären Ausdrücken

Literale

Reguläre Ausdrücke bestehen im Allgemeinen aus Symbolen und Zeichen (Literalen). In der nachstehenden Tabelle werden einige der häufig verwendeten Literale aufgelistet.

LiteralBeschreibung
\Escape-Zeichen für Sonderzeichen
.Platzhalter für ein beliebiges einzelnes Zeichen
\dPlatzhalter für eine beliebige Einzelziffer
[]Definition einer Wertemenge für einzelne Zeichen
[ – ]Definition eines Bereichs in einer Wertemenge für einzelne Zeichen
?Ein oder kein einzelnes Zeichen
*Verkettung von beliebig vielen Einzelzeichen
+Verkettung von beliebig vielen Einzelzeichen (mindestens ein Zeichen)
|Verkettung von zwei alternativen Ausdrücken
^Ankerzeichen für den Anfang einer Zeile
$Ankerzeichen für das Ende einer Zeile
\<Anfang eines Wortes
>Ende eines Wortes
\bAnfang oder Ende eines Wortes
\wJeder Buchstabe, jede Ziffer und jeder Unterstrich
\sLeerzeichen oder Tabulator

Beispiel

Wir haben als Beispiel diesen Text: ERP UP – Wissenswertes in SAP ERP und SAP S/4HANA. Nun möchten wir in diesem Text prüfen, ob der Begriff „ERP UP“ darin vorkommt. Es kann hierfür verschiedene Schreibweisen geben: ERP UP, ERP-UP, erp up, erp-up. Und genau hierfür erstellen und nutzen wir einen regulären Ausdruck, um diese Schreibweisen zu überprüfen. Der reguläre Ausdruck hierfür kann folgendermaßen aussehen:

[eE][rR][pP][ |-][uU][pP]

Hier gibt es weitere einfache Beispiele für reguläre Ausdrücke:

Regulärer AusdruckBeschreibungBeispiel
a?„a“-Zeichen oder nichts.a
a*Kein oder mehrere aufeinanderfolgende „a“-Zeichen.aa
a+Ein oder mehrere aufeinanderfolgende „a“-Zeichen.aa
a{3}Drei aufeinanderfolgende „a“-Zeichenaaa
a{3,}Drei oder mehrere aufeinanderfolgende „a“-Zeichenaaaa
a{3,6}Drei bis sechs aufeinanderfolgende „a“-Zeichenaaaaaa
\w{5}Beliebiges Wort mit fünf Buchstaben oder einer fünfstelligen ZahlERPUP
\d{10}10-stellige Zahl0123456789
[a-z]{5,}Fünf- oder mehrstelliges Wort in Kleinbuchstabenerpup
[a-zA-Z]Ein Buchstabe in Groß- oder KleinschreibungZ

Tool für reguläre Ausdrücke

Es gibt das kostenlose Tool regex101, mit dem Du kostenlos reguläre Ausdrücke erstellen und prüfen kannst. Gib doch einfach einen regulären Ausdruck und einen Text ein und überprüfe eigenständig das Ergebnis. Das geniale hierbei ist vor allem, dass man rechts auf Englisch die Erklärung hierfür angezeigt bekommt.

Mit regex101 reguläre Ausdrücke überprüfen

Reguläre Ausdrücke in ABAP

In der Programmiersprache ABAP kannst Du ebenfalls reguläre Ausdrücke verwenden. ABAP unterstützt reguläre Ausdrücke in den Anweisungen FIND und REPLACE und über die ABAP-Klassen CL_ABAP_REGEX und CL_ABAP_MATCHER. Die Klasse CL_ABAP_MATCHER wendet einen mit CL_ABAP_REGEX erzeugten regulären Ausdruck entweder auf eine Zeichenkette oder eine interne Tabelle an.

Verwendest Du einen syntaktisch falschen regulären Ausdruck, wird die Ausnahme CX_SY_INVALID_REGEX ausgelöst.

Ein regulärer Ausdruck kann syntaktisch korrekt sein, aber zu komplex für die Ausführung der ABAP-Anweisung FIND oder REPLACE. Wenn dem so ist, wird eine behandelbare Ausnahme der Klasse CX_SY_REGEX_TOO_COMPLEX ausgelöst.

Regulärer Ausdruck in ABAP – FIND

Du kannst mit dem ABAP-Begriff FIND reguläre Ausdrücke verwenden und damit nach einem bestimmten Suchmuster in einer Zeichenkette suchen. Die Syntax hierfür lautet folgendermaßen:

FIND REGEX <RegEx> IN <Text> RESULTS <Ergebnisse>.

Anstatt RESULTS kannst Du auch MATCH COUNT, MATCH OFFSET oder MATCH LENGTH angeben, um die Anzahl der Treffer, das Offset oder die Länge des Ergebnisses zu ermitteln.

Beim FIND-Befehl schreibt man die Ergebnisse der Suche in eine interne Tabelle des Typs MATCH_RESULT_TAB. Dabei handelt es sich um einen Tabellentyp, der als Zeilentyp die Struktur MATCH_RESULT enthält. Hierbei gibt es die wichtigen Attribute OFFSET und LENGTH. OFFSET enthält den Index im String, an dem der Teilstring gefunden wurde. Der Index beginnt mit 0. Sollte der Teilstring also an der ersten Stelle gefunden werden, enthält OFFSET den Wert 0. Das Attribut LENGTH gibt die Länge des Teilstrings an. Den gewünschten Teilstring kannst Du einfach durch folgenden Begriff ermitteln.

" Syntax
String+OFFSET(LENGTH)

" Beispiel der Variable lv_input
" An der vierten Stelle wird ein Teilstring der Länge 2 ermittelt
" lv_input = 'ERP UP'
lv_input+3(2) "UP

Bei der Suche wird die sogenannte „leftmost-longest“-Regel angewendet. Dabei wird der Teil der Zeichenkette als Erstes ermittelt, der am weitestens links steht. Gibt es mehrere Übereinstimmungen, wird der längste Teil ermittelt.

Als Beispiel möchten wir Straßennamen validieren. Wir gehen zur Vereinfachung davon aus, dass ein Straßenname immer mit „Str.“ endet. Dabei soll die Groß- und Kleinschreibung von „Str.“ ignoriert werden. Hierbei wähle ich folgenden Straßennamen: „Haupstr.“. Hierfür kann man als Beispiel folgenden regulären Ausdruck verwenden:

.*[sS]tr\.

In einem ABAP-Programm kann es bspw. folgendermaßen aussehen:

DATA: lv_regex        TYPE c LENGTH 10 VALUE '.*[sS]tr\.',
      lv_input_regex  TYPE text100,
      lt_regex_result TYPE match_result_tab,
      ls_regex_result TYPE match_result.

lv_input_regex = 'Haupstr.'.

FIND REGEX lv_regex IN lv_input_regex RESULTS lt_regex_result.

IF sy-subrc = 0.
  READ TABLE lt_regex_result INDEX 1 INTO ls_regex_result.
  WRITE: / lv_input_regex+ls_regex_result-offset(ls_regex_result-length).
ELSE.
  WRITE: / 'Nichts gefunden'.
ENDIF.

Findet der REGEX-Befehl kein Teilstring, wird der Rückgabewert 4 in der Systemvariable sy-subrc zurückgegeben.

Außerdem kannst Du die Anweisung „FIND ALL OCCURRENCES OF REGEX“ verwenden, um die Anzahl der Teilstrings in einer Zeichenkette zu ermitteln. Die Syntax hierfür lautet:

FIND ALL OCCURRENCES OF REGEX <RegEx> in <Text> RESULTS <Ergebnisse>.

In einem ABAP-Programm kann es bspw. folgendermaßen angewendet werden:

DATA: lv_regex       TYPE c LENGTH 12 VALUE '[eE][rR][pP]',
      lv_input_regex TYPE text100,
      lv_count       TYPE i.


lv_input_regex = 'ERP UP, ERP-UP, erp up, erp-up'.
FIND ALL OCCURRENCES OF REGEX lv_regex IN lv_input_regex MATCH COUNT lv_count.

IF sy-subrc = 0 AND lv_count > 0.
  WRITE: / 'Der Begriff "ERP" kommt ', lv_count, ' mal vor.'.
ELSE.
  WRITE: / 'Nichts gefunden'.
ENDIF.

Regulärer Ausdruck in ABAP – REPLACE

Du kannst mit dem ABAP-Begriff REPLACE reguläre Ausdrücke verwenden und damit in einem Text einen bestimmten Teil entfernen. Die Syntax hierfür lautet folgendermaßen:

REPLACE REGEX <RegEx> IN <Text> WITH <Ersatz>.

Dabei wird der erste gefundene Teilstring ersetzt und nicht alle. Ich möchte das anhand von einem Beispiel näher erläutern. Wir haben erneut unseren Text „ERP UP, ERP-UP, erp up, erp-up“ und den regulären Ausdruck „[eE][rR][pP]“, um nach dem Wort „ERP“ zu suchen. Im Text kommt dieser vier mal vor. Wenn ich nun die folgende Anweisung verwende, wird nur der erste Treffer ausgetauscht:

"Davor: ERP UP, ERP-UP, erp up, erp-up
REPLACE REGEX lv_regex IN lv_input_regex WITH ''.
"Danach:  UP, ERP-UP, erp up, erp-up

In einem Beispielprogramm wird es folgendermaßen integriert:

DATA: lv_regex       TYPE c LENGTH 12 VALUE '[eE][rR][pP]',
      lv_input_regex TYPE text100.


lv_input_regex = 'ERP UP, ERP-UP, erp up, erp-up'.

REPLACE REGEX lv_regex IN lv_input_regex WITH ''.

IF sy-subrc = 0.
  WRITE: / lv_input_regex.
ELSE.
  WRITE: / 'Nichts gefunden'.
ENDIF.

Wenn Du nun alle möglichen Treffer austauschen möchtest, verwendest Du die Anweisung „REPLACE all OCCURRENCES OF REGEX“. Die Syntax hierfür lautet folgendermaßen:

REPLACE ALL OCCURRENCES OF REGEX <RegEx> IN <Text> WITH <Ersatz>.

Wenn wir diese Anweisung im oberen Programm verwenden, ist die Ausgabe “ UP, -UP, up, -up“, da alle Begriffe „ERP“ ersetzt werden.

Wenn man ein ungültiges Muster nach dem Zusatz „WITH“ angibt, wird die Ausnahme CX_SY_INVALID_REGEX_FORMAT ausgelöst.

Regulärer Ausdruck in ABAP – CL_ABAP_REGEX

Anstatt direkt den regulären Ausdruck in FIND und REPLACE anzugeben, kannst Du die ABAP-Klasse CL_ABAP_REGEX verwenden. Hierfür gibst Du bei der Erstellung einer Instanz im Konstruktor den regulären Ausdruck an und gibst diese im ABAP-Befehl „FIND“ an.

Wenn wir bei der Suche eines Wortes, das „Str.“ enthält bleiben, kann ein Beispielprogramm folgendermaßen aussehen:

DATA: lv_regex        TYPE c LENGTH 10 VALUE '.*[sS]tr\.',
      lc_regex        TYPE REF TO cl_abap_regex,
      lv_input_regex  TYPE text100,
      lt_regex_result TYPE match_result_tab,
      ls_regex_result TYPE match_result.

lv_input_regex = 'Haupstr.'.

TRY.
    CREATE OBJECT lc_regex
      EXPORTING
        pattern = lv_regex
      .
  CATCH cx_sy_regex .

ENDTRY.

FIND REGEX lc_regex IN lv_input_regex RESULTS lt_regex_result.

IF sy-subrc = 0.
  READ TABLE lt_regex_result INDEX 1 INTO ls_regex_result.
  WRITE: / lv_input_regex+ls_regex_result-offset(ls_regex_result-length).
ELSE.
  WRITE: / 'Nichts gefunden'.
ENDIF.

Du kannst die Instanz der ABAP-Klasse insgesamt in folgenden Anweisungen anwenden:

  • FIND REGEX
  • FIND ALL OCCURRENCES OF REGEX
  • REPLACE REGEX
  • REPLACE ALL OCCURRENCES OF REGEX

In den vorherigen Beispielen kannst Du somit die Variable lv_regex mit lc_regex ersetzen und erhältst das gleiche Ergebnis.

Regulärer Ausdruck in ABAP – CL_ABAP_MATCHER

Die ABAP-Klasse CL_ABAP_MATCHER ist ebenfalls sehr mächtig und kann im Rahmen von regulären Ausdrücken verwendet werden. Bei der Erstellung einer Instanz dieser Klasse wird der reguläre Ausdruck in der ABAP-Klasse CL_ABAP_REGEX gehalten.

Mit der statischen Methode kannst Du z.B. überprüfen, ob anhand eines regulären Ausdrucks ein Muster in einem Text zutrifft. Das ABAP-Programm kann bspw. folgendermaßen aussehen:

DATA: lv_regex       TYPE c LENGTH 12 VALUE '[eE][rR][pP]',
      lv_input_regex TYPE text100,
      lc_matcher     TYPE REF TO cl_abap_matcher,
      lv_success     TYPE flag.


lv_input_regex = 'ERP UP, ERP-UP, erp up, erp-up'.

CALL METHOD cl_abap_matcher=>contains
  EXPORTING
    pattern = lv_regex
    text    = lv_input_regex
  RECEIVING
    success = lv_success.

IF lv_success IS NOT INITIAL.
  WRITE: / 'Muster im Text gefunden'.
ELSE.
  WRITE: / 'Nichts gefunden.'.
ENDIF.

Alternativ kannst Du die statische Methode CREATE erwenden, um eine Instanz zu erzeugen und mit der Methode FIND_NEXT prüfen, ob das Suchmuster enthalten ist.

DATA: lv_regex       TYPE c LENGTH 12 VALUE '[eE][rR][pP]',
      lv_input_regex TYPE text100,
      lc_matcher     TYPE REF TO cl_abap_matcher.


lv_input_regex = 'ERP UP, ERP-UP, erp up, erp-up'.

lc_matcher = cl_abap_matcher=>create( pattern     = lv_regex
                                      text        = lv_input_regex ).

IF lc_matcher->find_next( ) = 'X'.
  WRITE: / 'Suchmuster im Text vorhanden.'.
ELSE.
  WRITE: / 'Nichts gefunden.'.
ENDIF.

Möchtest Du mit der Klasse CL_ABAP_MATCHER einen Teil des Textes ersetzen, kannst Du die Methode REPLACE_NEXT oder REPLACE_ALL nutzen.

DATA: lv_regex       TYPE c LENGTH 12 VALUE '[eE][rR][pP]',
      lv_input_regex TYPE text100,
      lc_matcher     TYPE REF TO cl_abap_matcher.

lv_input_regex = 'ERP UP, ERP-UP, erp up, erp-up'.

lc_matcher = cl_abap_matcher=>create( pattern     = lv_regex
                                      text        = lv_input_regex ).

" Ersten Treffer ersetzen
lc_matcher->replace_next( '' ).

" Alle Treffer ersetzen
lc_matcher->replace_all( '' ).

WRITE: / lc_matcher->text.

Über den Autor

Andreas Geiger

Mein Name ist Andreas Geiger und ich bin ein erfahrener Senior SAP Berater. Mit mehr als 10 Jahren Berufserfahrung habe ich mehrere SAP-Projekte erfolgreich abgeschlossen und umfangreiche Kenntnisse in verschiedenen Bereichen wie SAP FI, SAP MM und ABAP erworben. Nun möchte ich mein Wissen mit Dir teilen, um Dir einen Mehrwert zu bieten und Dich bei Deiner täglichen Arbeit mit dem SAP-System zu unterstützen.

Mehr zu ERP UP

ERP UP unterstützen

Wenn Du mit ERP UP zufrieden bist, kannst Du mich gerne unterstützen. Dabei gibt es unzählige Möglichkeiten, wie Du mich einfach und schnell unterstützen kannst. Wie Du genau ERP UP unterstützen kannst, erfährst Du hier. Vielen Dank.

Schreibe einen Kommentar