Ansicht
Dokumentation

ABAPSHEET_STRING_PROCESSING - SHEET STRING PROCESSING

ABAPSHEET_STRING_PROCESSING - SHEET STRING PROCESSING

CPI1466 during Backup   Fill RESBD Structure from EBP Component Structure  
This documentation is copyright by SAP AG.
SAP E-Book

String Processing

This cheat sheet provides an overview on selected syntax options when working with strings. It serves as a collection of syntax and code snippets in one place for your reference. For more details and syntax options, refer to the respective topic in the ABAP Keyword Documentation.

Introduction

ABAP offers plenty of options for processing character strings. The options include ABAP statements, character string expressions and built-in string functions:

  • Expressions and string functions can help make your ABAP code more concise and straightforward. For example, string operations can be done directly in operand position and, thus, you can avoid temporary variables.
  • In most cases, string functions offer the same functionality as the corresponding ABAP statements. If string functions return strings, the strings are always of type string.
  • In ABAP statements, modify operations on strings are frequently done on the source field which is the target field at the same time. String functions never modify the source field. Instead and if applicable, the modified string is provided as a return value.

Typical data types for character strings in ABAP are as follows:

  • string
  • Data objects of this type have a variable length, i. e. the length can change during the execution of ABAP programs (hence, they are also referred to as dynamic data objects)

  • When declaring a variable-length string, you can use backquotes (`...`). You can also use pipes ($|...$|; see string templates).

  • c
  • Data objects of this type have a fixed length.

  • When declaring a fixed-length string, you use single quotes ('...').

Differences of variable-length and fixed-length strings

  • Initial value: The initial value of variable-length strings is an empty string with length 0. Fixed-length strings have a standard length of 1 character. The initial value is a blank.
  • Performance: Data objects of both type c and string are considered as elementary data objects. However, data objects of type string are internally managed as references and are, thus, considered as deep. This fact enables the performance boosting concept of sharing for data objects of this type when making value assignments.
  • Length: Theoretically, a variable-length string can use up to 2 GB. The maximum length of a fixed-length string is 262143 characters.
  • Treating trailing blanks: Fixed-length strings usually ignore trailing blanks, variable-length strings respect them.
  • Flexibility: Variable-length strings are more flexible than fixed-length strings because you can easily shorten or extend them without worrying that, for example, characters are truncated when processing.

So, when to actually use what? Fixed-length strings make sense for really determining a maximum or mandatory length, e. g. a country code that must consist of two characters maximally and mandatorily or input fields in forms that should not exceed a certain length. If restricting a string is not relevant, variable-length strings are a good choice.

There are further character-like data types for fixed-length strings, for example, n for numeric text literals. The standard length and the value range is the same as for c, however, only digits (0 to 9) are valid values. The initial value is "0". Here, you must pay attention because the field restrictions are not enforced, hence, fields may contain invalid data. The type is especially used for digits that are not meant for arithmetic calculations like zip codes or article numbers.

DATA zip_code TYPE n LENGTH 5 VALUE '12345'.
DATA isbn_number TYPE n LENGTH 13 VALUE '1234567890123'.

The data type n, byte-like data types (x, xstring), d referring to date and t referring to time (which are both specializations of the type c) are not part of this cheat sheet.

Declaring Character-like Data Types and Objects

Character-like data types and objects are declared like other types and objects using TYPES and DATA statements. This cheat sheet focuses on the built-in types c and especially on string in most examples.

Syntax examples:

"Type declarations using built-in types
TYPES: c_type   TYPE c LENGTH 3, "Explicit length specification
       str_type TYPE string.

"Data object declarations using built-in, local and DDIC types
DATA: flag  TYPE c LENGTH 1, "Built-in type
      str1  TYPE string, "Built-in type
      char1 TYPE c_type, "Local type
      str2  LIKE str_a1, "Deriving type from a local data object
      str3  TYPE str_type, "Local type
      char2 TYPE s_toairp, "DDIC type (used e. g. for a field in the SPFLI demo table)
      char3 TYPE spfli-carrid. "Using the type of a DDIC table component

"You might also stumble upon declarations with type c and the length
"specified in parentheses. Not recommended so as to not confuse with the
"use of parentheses in dynamic programming.
DATA char(4) TYPE c.

Creating Strings and Assigning Values

You create strings by declaring character-like data objects and assigning values to them. Here, you can provide default values directly when declaring the data objects or assign values using the assignment operator =. To do both, data object declaration and value assignment, in one go, you can make use of inline declaration that supports declarations in write positions. In doing so, a variable specified in parentheses preceded by DATA on the left side of the assignment operator automatically derives a data type from the operand on the right. This helps make your programs leaner.

Syntax examples:

"Data object declarations including default values with VALUE
DATA: flag TYPE c LENGTH 1 VALUE 'X', "Single quotes
      str1 TYPE string VALUE `Hallo!`. "Backquotes

"More data object declarations
DATA: char  TYPE c LENGTH 5,
      html  TYPE string,
      str   LIKE html.

"Value assignments
char = 'ab123'.
html = `<p>hallo</p>`.
str  = `This is a backquote: ``.`. "Escape backquotes with another one
"If possible, avoid unnecessary type conversion
str = 'abc'. "Fixed-length string assigned to data object of type string

"Inline declarations
DATA(char_b) = 'abcd'.
DATA(str_b)  = `efgh`.
"Since char_b is of type c length 4 (the length is also derived),
"characters are truncated in the following example assignment
char_b = 'ijklmnopq'. "The data object is only assigned ijkl

"Treating trailing blanks
DATA(char_c) = 'ab   '.
DATA(str_c)  = `cdefgh`.
str_c = char_c. "Result: ab; trailing blanks are not respected

Chaining Strings

When assigning strings, not only data objects can be placed on the right side. Various expressions and strings can be chained using the concatenation operator &&. Alternatively, you might do the chain strings using string templates and the options for concatenating strings as shown further down.

text3 = text1 && ` ` && text2 && `!`.

String Templates

Using string templates, you can construct strings from literals and ABAP expressions very elegantly. You construct the string using the pipe symbol at the beginning and end of the string template ($|...$|). To embed expressions, you include them within curly brackets (${ expr $}). As mentioned above, you can also concatenate multiple strings using string templates.

Syntax examples:

"Data object declarations
text1 = `Hallo`. "String created using backquotes.
text2 = |how|. "Strings created using pipes.
text3 = |are|.

"String construction using literals and expressions
"A blank (not within the curly brackets) means a blank in the resulting string.
"The expression must be convertible to a string.
text4 = |{ text1 } { cl_abap_syst=>get_user_name( ) }, { text2 } { text3} you?|.

"Chaining of string templates using && since string templates cannot stretch
"over multiple lines
text5 = |{ text1 } | && |and| && | goodbye.|

String templates interpret certain character combinations as control characters. For example, \n is interpreted as the hexadecimal value for setting a new line. Plus, string templates support various formatting options. Check the ABAP Keyword Documentation for all options.

Syntax examples:

"Control characters
text4 = |{ text1 }\n{ text2 }\n{ text3 }\nyou?|. "\n interpreted as line breaks

"Various formatting options
"Time and date
"Formatting according to the user master data
date = |The date is { cl_abap_context_info=>get_system_date( ) DATE = USER }.|.
"Formatting in accordance with ISO 8601
time = |The time is { cl_abap_context_info=>get_system_time( ) TIME = ISO }.|.
"Formatting to UTC; date and time are represented in ISO 8601
ts = |Timestamp: { utclong_current( ) TIMESTAMP = SPACE }.|.

"Lower and upper case
t1 = |AbCdEfG|.
t2 = |{ t1 CASE = LOWER }|.
t3 = |{ t1 CASE = UPPER }|.

"Width and alignment
t4 = |{ 'Left' WIDTH = 20 ALIGN = LEFT }<---|.
t5 = |{ 'Center' WIDTH = 20 ALIGN = CENTER }<---|.
"PAD: Used to pad any surplus places in the result with the specified character.
t6 = |{ 'Right' WIDTH = 20 ALIGN = CENTER PAD = '.' }<---|.

"Numbers
t7 = |{ - 2 / 3 DECIMALS = 3 }|. "Format the result to only hold 3 decimals

  • String templates cannot be used in user dialogs since they must be translatable. Hence, these texts should be realized in OTR texts or T100 messages.
  • Escape \|{} in string templates using \, i. e. \\ means \.

Determining the Length of Strings

To determine the length of a string you can use the string function strlen. Note that the result depends on the type of the literal, i.e. the result of a literal of type string includes trailing blanks. A fixed-length string does not include them. To exclude trailing blanks in all cases irrespective of the data type, you can use the built-in function numofchar.

Syntax examples:

"strlen
len_c   = strlen( 'abc   ' ). "3
len_str = strlen( `abc   ` ). "6

"numofchar
len_c   = numofchar( 'abc   ' ). "3
len_str = numofchar( `abc   ` ). "3

Concatenating Strings

As already touched on above, two or more strings can be concatenated using the concatenation operator && and string templates. Alternatively, you can use CONCATENATE statements. It is also possible to concatenate lines of internal tables into a string to avoid a loop. In a more modern way, you can make use of the string function concat_lines_of.

Syntax examples:

"&& and string template
t1 = `Ha` && `llo`. "Hallo
t2 = `Ha` && `llo` && ` ` && txt1. "Hallo Hallo
t3 = |{ txt1 }? { txt2 }!|. "Hallo? Hallo Hallo!

"CONCATENATE statements
CONCATENATE t1 t2 INTO t3.
CONCATENATE t1 t2 t3 INTO DATA(t4). "Multiple data objects and target declared inline

"You can also add a separation sign using the addition SEPARATED BY
CONCATENATE t1 t2 INTO t SEPARATED BY space.
CONCATENATE t1 t2 INTO t SEPARATED BY '#'.

"Keeping trailing blanks in the result when concatenating fixed-length
"strings. The ones of variable-length strings are respected by default.
CONCATENATE 'a  ' 'b  ' 'c  ' INTO t RESPECTING BLANKS.

"Concatenating lines of internal tables into a string
CONCATENATE LINES OF itab INTO t SEPARATED BY space.
"Using concat_lines_of
t = concat_lines_of( table = itab ). "Without separator
t = concat_lines_of( table = itab sep = ` ` ). "With separator

Splitting Strings

You can use SPLIT statements to split strings in multiple segments. The result of the splitting can be stored in separate data objects or internal tables that have a character-like line type. Note that if the specified targets are less than the segments retrieved by the splitting, the last target receives the rest of the segments that have not yet been split. If there are more targets specified, the targets not receiving a segment are initialized. Hence, specifying individual targets with SPLIT statements is useful if the number of expected segments is known. Otherwise, splitting into tables is a good choice.

If you want to get the value of a specific segment, you can use the string function segment.

Syntax examples:

t1 = `Hallo,world,12345`.
SPLIT t1 AT `,` INTO t2 t3 t4.
"Less data objects than possible splittings; t3 contains world,12345
SPLIT t1 AT `,` INTO t2 t3.
"Split into internal table
DATA itab TYPE TABLE OF string.
SPLIT t1 AT ',' INTO TABLE itab. "Strings added to itab without comma

"String function segment; index parameter: number of segment
seg = segment( val = t1 index = 2 sep = `,` ). "seg: world

Modifying Strings

Transforming to Lower and Upper Cases

The string functions to_lower and to_upper transform characters of a string to either lower or upper case and store the result in a target variable. If the transformation should be applied to the source directly, you can use TRANSLATE statements.

Syntax examples:

"String functions
upper_case = to_upper( `abap` ). "ABAP
lower_case = to_lower( `SOME_FILE.Txt` ). "some_file.txt

"TRANSLATE statements
DATA(txt) = `Hallo`.
TRANSLATE txt TO UPPER CASE. "HALLO
TRANSLATE txt TO LOWER CASE. "hallo

Shifting Content

You can shift content within a string to a specific position on the left or right of a string. SHIFT statements have different additions for specific use cases.

In a more modern way, you can use the string functions shift_left and shift_right that store the result in a variable. These functions offer an additional functionality. The sub parameter can be used to specify a substring. All substrings in the string that match the specified value in sub either on the left or right side of the string are removed.

Syntax examples:

"SHIFT statements
DATA(a) = `hallo`.
SHIFT a. "No addition; string shifted one place to the left: allo
SHIFT a BY 2 PLACES. "Without direction, left by default: llo
SHIFT a BY 3 PLACES RIGHT. "With direction, variable-length strings are extended: ___hallo
"Here, _ represents a blank.
DATA(b) = 'hallo'.
SHIFT b BY 3 PLACES RIGHT. "Fixed-length string: ___ha
"CIRCULAR addition: characters that are moved out of the string are
"added at the other end again
SHIFT a BY 3 PLACES LEFT CIRCULAR. "lohal
SHIFT a UP TO `ll`. "Move characters up to a specific character set: llo
"Deleting leading and trailing characters
DATA(c) = `   hallo   `.
DATA(d) = c.
SHIFT c LEFT DELETING LEADING ` `. "hallo___
SHIFT d RIGHT DELETING TRAILING ` `. "___hallo

"String functions with parameters
txt = shift_left( val = a places = 3 ). "lo
txt = shift_left( val = a circular = 2 ). "lloha

"Note that shift_right does not extend a variable-length string.
txt = shift_right( val = a places = 3 ). "ha
txt = shift_right( val = `blanks:   ` sub = ` ` ). "blanks:
txt = shift_right( val = `blanks:   ` ). "Same result: blanks:

Condensing Strings

You can use CONDENSE statements or the string function condense to remove blanks in strings. The advantage of using the string function is that you can also specify random characters to be removed and not only blanks.

Syntax examples:

"CONDENSE statements
DATA(a) = ' ab cd '.
DATA(b) = '    ef   gh ij   '.
DATA(c) = ' kl  mn   op '.
CONDENSE a. "Trailing and leading blanks are removed: ab cd
CONDENSE b. "It also replaces sequences of multiple blanks with a single blank: ef gh ij
CONDENSE c NO-GAPS. "Removes all blanks: klmnop
"When NO-GAPS is used with variable-length strings, trailing blanks remain removed.

"String function condense
DATA(d) = ` ab   cd `.
"No parameters specified, i. e. their default values are provided.
"Works like CONDENSE statement without the NO-GAPS addition.
txt = condense( d ). "ab cd
"Parameters del/to not specified. from parameter with initial string
"(could also be a text field literal: from = ' '). This way, leading and
"trailing blanks are removed.
txt = condense( val = d from = `` ). "ab   cd
"Parameter to specified with an initial string. No other parameters.
"Works like CONDENSE statement with the NO-GAPS addition.
txt = condense( val = d  to = `` ). "abcd
"Parameter del specifies the leading/trailing characters to be removed.
txt = condense( val = `##see###you##` del = `#` ). "see###you
"If from and to are specified along with del, leading/trailing
"characters specified in del are first removed. Then, in the remaining string, all
"substrings composed of characters specified in from are replaced with
"the first character of the string specified in the to parameter
txt = condense( val  = `  Rock'xxx'Roller` del  = `re `
                from = `x` to = `n` ). "Rock'n'Roll

Reversing Strings

The string function reverse reverses a string:

res = reverse( `paba` ). "abap

Inserting Content

The string function insert inserts a substring into a random position within a given string. Using various parameters, you can construct your desired string:

  • val: Original string.
  • sub: Substring.
  • off: Optionally sets the offset, i. e. the position where to add the substring. The default value is 0. When using the function with the default value, the result is like concatenating a string with && (like res = sub && text).

Syntax examples:

res = insert( val = `abcghi` sub = `def` off = 3 ). "abcdefghi
res = insert( val = `abcghi` sub = `def` ). "defabcghi

Processing Substrings

Using the string function substring, you can specify the position (parameter off) and the length (len) of a substring that should be extracted from a given string (val). At least one of the two parameters off or len must be specified. The default value of off is 0, i. e. when using the default value, the substring is extracted from the beginning of the string. Not specifying len means that the rest of the remaining characters are considered. If the offset and length are greater than the actual length of the string, the exception CX_SY_RANGE_OUT_OF_BOUNDS is raised.

You might also stumble on the syntax for accessing substrings via offset and length specification using the + sign after a variable. Here, the length is specified within parentheses. Providing an asterisk (*) means to consider the rest of the remaining string. This syntax option even enables write access on substrings for fixed-length strings. Read access is possible for both fixed-length and variable-length strings. However, this syntax might be confused with the use of tokens in the context of dynamic programming.

There are further string functions available to deal with substrings, for example, substring_after, substring_before, substring_from and substring_to.

These functions offer more options in terms of parameters, for example, a PCRE regular expression which are dealt with further down.

Syntax examples:

str = `Lorem ipsum dolor sit amet`.
res = substring( val = str off = 6 ). "ipsum dolor sit amet
res = substring( val = str len = 5 ). "Lorem
res = substring( val = str off = 6 len = 5 ). "ipsum

chars = 'Lorem ipsum dolor sit amet'.
res = chars+0(5). "Lorem
res = chars+12(*). "dolor sit amet
CLEAR chars+11(*). "Lorem ipsum
chars+0(5) = 'Hallo'. "Hallo ipsum dolor sit amet

"Further string functions
string = `aa1bb2aa3bb4`.
res = substring_after( val = string sub = `aa` ). "1bb2aa3bb4 (only the first occurrence is considered)
res = substring_after( val = string sub = `aA` occ = 2 len = 4 case = abap_false ). ""3bb4
res = substring_before( val = string sub = `b2`  ). "aa1b
res = substring_from( val = string sub = `a3` ). "a3bb4 (includes the substring in sub)
res = substring_to( val = string sub = `3b` ). "aa1bb2aa3b (includes the substring in sub)

Searching and Replacing

In ABAP, there are a lot of options to carry out search and replace operations with strings. This includes the use of the prominent ABAP statements FIND and REPLACE or the more modern built-in string functions find and replace, among others, with their considerable amount of additions or parameters respectively. Many of these options support carrying out rather simple operations considering only single characters or more complex, pattern-based operations on character sequences using PCRE regular expressions.

Searching for Specific Characters

  • You can use the comparison operators CA (contains any) or its negation NA (contains not any) in comparison expressions to determine if any character of a given character set is contained in a string. Such an expression is true if at least one character is found.
  • The search is case-sensitive.

  • The system variable sy-fdpos contains the offset of the first found character. If nothing is found, sy-fdpos contains the length of the string.

  • Note that position 0 stands for the very first position.

  • The string functions find_any_of or its negation find_any_not_of return the offset of the occurrence of any character contained in a substring.
  • If nothing is found, the value -1 is returned

  • There are further optional parameters possible. For example, the specification of occ determines the search direction, i. e. a positive value means the search is performed from left to right. A negative value means searching from right to left.

  • If the position of characters is not of interest but rather how often characters occur in a string, you can use the string functions count_any_of or its negation count_any_not_of.
  • To determine if a string only contains a specific set of characters, you can use the comparison operators CO (contains only) or its negation CN (contains not only) in comparison expressions.
  • Regarding CO, a comparison is true if the left operand only contains characters that are also contained in the right operand. If the comparison is not true, you can get the position of the first character from text that is not contained in the character set via sy-fdpos. Regarding CN, a comparison is true if a string not only contains characters from the character set.

Syntax examples:

str = `cheers`.
IF str CA `aeiou` ... "true, sy-fdpos = 2
IF str NA `xyz`... "true, sy-fdpos = 6

res = find_any_of( val = str sub = `aeiou` ). "2
res = find_any_not_of( val = str sub = `c` ). "1

res = count_any_of( val = str  sub = `e` ). "2
res = count_any_not_of( val = str  sub = `s` ). "5

IF str CO `rs` ... "not true, sy-fdpos = 0
IF str CN `cheers` ... "not true, sy-fdpos = 6

Replacing Specific Characters in Strings

You can use the string function translate to replace specific characters by others. Here, the parameter from denotes the characters to be placed in a string and to specifies the target characters. The replacement is done as follows: Each character specified in from is replaced by the character in to that is on the same position, i. e. the second character in from is replaced by the second character specified in to. If there is no equivalent in to, the character in from is removed from the result.

Using TRANSLATE statements, you can carry out replacements directly on the source field.

Syntax examples:

str = `___abc_def_____ghi_`.
res = translate( val = str from = `hi_` to = `ZZ` ). "abcdefgZZ
res = translate( val = str from = `_`  to = `ZZ` ). "ZZZabcZdefZZZZZghiZ

"TRANSLATE statement. The value after USING is interpreted as a string composed of character pairs.
"Starting with the first pair, a search is performed in text for the
"first character in every pair and each occurrence is replaced with the
"second character of the pair.
TRANSLATE str USING `_.aZgY`. "...Zbc.def.....Yhi.

Searching for Substrings in Strings

  • For simple substring searches, you can use the comparison operators CS (contains string) or its negation NS (contains no string) in comparison expressions. Here, the search is not case-sensitive. The system variable sy-fdpos contains the offset of the found substring. If the substring is not found, sy-fdpos contains the length of the searched string.
  • For more complex and iterating search operations, it can be beneficial to use FIND statements or the string function find. If you are only interested in the offset of a substring within a string, the string function offers more options than using the logical operator, for example, you can specify if the search should be case-sensitive or not. You can also further restrict the search using parameters.
  • Since the string function find is derived from the ABAP statement FIND, FIND covers the same functionality as mentioned above, too, using the multiple addition options which are not dealt with here. However, FIND statements store the results of all occurrences of substrings within a string in an internal table of type MATCH_RESULT_TAB. For example, the component offset contains the position of an individual finding. Furthermore, you can also search through internal tables having a character-like data type.

Syntax examples:

str = `cheers`.
IF str CS `rs` ... "true, sy-fdpos = 4
IF str NA `xyz`... "not true, sy-fdpos = 6

"String function find
txt = `Pieces of cakes.`.
res = find( val = txt sub = `OF` case = abap_false  ). "7
res = find( val = txt sub = `hallo` ). "-1 (no finding returns -1)
res = find( val = txt sub = `ce` off = 1 len = 7 ). "3
"Parameter occ: Positive value means the nth position from the left,
"a negative value the nth position from the right
res = find( val = txt sub = `es` occ = -1 ). "13

"String function count
res = count( val = txt sub = `es` ). "2

"Return all positions of findings in an internal table.
"Using inline declaration, the internal table receives the appropriate type automatically.
FIND ALL OCCURRENCES OF SUBSTRING `es` IN txt RESULTS DATA(itab).
"itab has two lines including 4 and 13 in the offset component

"Search in internal tables and return all positions
DATA(tab) = VALUE string_table( ( `abcdZZ` ) ( `efgZZh` ) ( `ZZijkl` ) ).
FIND ALL OCCURRENCES OF SUBSTRING `ZZ` IN TABLE tab RESULTS DATA(it).
"The table it has 3 lines including these offsets for the findings: 4, 3, 0

Replacing Substrings in Strings

To store the result of a substring replacement in a separate variable, you can use the replace. Using REPLACE statements, you can carry out replacements on strings directly (including substrings which is not possible with the string function). Regarding the multiple additions REPLACE offers, REPLACE is syntactically similar to FIND. In contrast to the function find, you cannot restrict the search area using replace. However, you have the parameter with that specifies the replacement text. Regarding the parameters:

  • sub: Specifies the substring to be replaced.
  • case: Sets the case sensitivity.
  • occ: Specifies the number of occurrences of a substring. The default value is 1, i. e. the first occurrence starting from the left. Setting occ to 0 means that all occurrences are considered for the replacement.

Syntax examples:

str = `abc def ghi abc`.
t = replace( val = str sub = `def` with = `###` ). "abc ### ghi abc
t = replace( val = str sub = `ABC` with = `###` case = abap_false occ = 2 ). "abc def ghi ###
t = replace( val = str sub = `abc` with = `###` occ = 0 ). "### def ghi ###

"REPLACE statements with selected additions
REPLACE `abc` IN str WITH `###`. "### def ghi abc
REPLACE ALL OCCURRENCES OF `abc` IN str WITH `###`. "### def ghi ###
REPLACE `aBC` IN str WITH `###` IGNORING CASE. "### def ghi abc
REPLACE SECTION OFFSET 4 LENGTH 7 OF str WITH `###`. "abc ### abc

Pattern-Based Searching and Replacing in Strings

You can carry out complex search and replace operations based on patterns. PCRE regular expressions help you process strings effectively. Do not use POSIX regular expression any more since they are obsolete. XPath and XSD regular expressions are not covered here.

Simple Pattern-Based Searching Using Comparison Operators

For simple patterns, you can use the comparison operators CP (conforms to pattern) or its negation NP (does not conform to pattern) in comparison expressions to determine if a set of characters is contained in a string that matches a certain pattern. For the patterns, you can use the following special characters:

Special Character Details
* Any character sequence (including blanks).
+ Any character (only one character, including blanks).
# Escaping symbol. The following character is marked for an exact comparison.

Patterns are not case-sensitive except for characters marked by #. If a pattern is found, the system variable sy-fdpos returns the offset of the first finding. Otherwise, it contains the length of the searched string.

str = `abc_def_ghi`.
"Pattern: f is preceded by any character sequence, must be followed
"by _ and then followed by any character sequence
IF str CP `*f#_*`. ... "true; sy-fdpos = 6

"Pattern: i is not followed by another character
IF str NP `i+`. ... "true; sy-fdpos = 11 (length of searched string)

Complex Searching and Replacing Using Regular Expressions

Excursion: Common Regular Expressions

There are various options to carry out complex searching in strings using PCRE expressions. They can be fairly complex. The following overview shows common PCRE expressions with simple examples.

Characters and character types

Expression Represents Example Matches Doesn't Match
. Any single character . a, 9, Ä, # aa, empty
\d Any digit (0-9) \d 1, 3, 7 A, b, c
\D Any character that is not a digit, equivalent to [^0-9] \D D, e, f 4, 5, 8
\s Any whitespace character such as a blank, tab and new line \s \lbr (string: hi there) the blank in between hi
\S Any character that is not a whitespace \S \lbr (string: a 1) a, 1 the blank in between
\w Any word character (letter, digit or the underscore), equivalent to [a-zA-Z0-9_] \w \lbr (string: ab 12) a, b, 1, 2 the blank in between
\W Any character that is not a word character, equivalent to [^a-zA-Z0-9_] \W \lbr (string: cd 34) the blank in between c, d, 3, 4
\... To include special characters like [ ] \ / ^, use \ to escape them. \\ \ /

Repetitions and Alternatives

Expression Represents Example Matches Doesn't Match
r* Zero or more repetitions of r ab* a, ab, abb, abbb b, aba
r+ One or more repetitions of r ab+ ab, abb, abbb a, b, aba
r{m,n} Between m and n repetitions a{2,4} aa, aaa, aaaa a, aaaaa, aba
r{m} Exactly m repetitions a{3} aaa a, aa, aaaa, bbb
r? Optional r ab?a aa, aba abba, aca
r|s Matching alternatives, i. e. r or s a+|b+ a, b, aa, bb, aaa ab, aabb

Character Sets, Ranges, Subgroups and Lookarounds

Expression Represents Example Matches Doesn't Match
[aA1-] Character set, matches a single character present in the list [aA1-] a, A, 1, - b, B, cc, 3
[a-z0-9] Character range, matches a single character in the specified range, note that ranges may be locale-dependent [a-c0-5] b, c, 2, 4 d, Z, x, 9
[^aA1] Negation, matches any single character not present in the list [^aA1] b, C, 3, - a, A, 1
[^0-9] Negation, matches any single character not within the range [^0-9] a, B, c 1, 2, 3
(...) Capturing group to group parts of patterns together a(b|c)a aba, aca aa, abca
(?=...) Positive lookahead, returns characters that are followed by a specified pattern without including this pattern a(?=b) \lbr (string: abc ade) the first a the second a
(?!...) Negative lookahead, returns characters that are not followed by a specified pattern without including this pattern a(?!b) \lbr (string: abc ade) the second a the first a
(?<=...) Positive lookbehind, returns characters that are preceded by a specified pattern without including this pattern (?<=\s)c \lbr (string: ab c abcd) the first c since it is preceded by a blank the second c
(?&lt;!...) Negative lookbehind, returns characters that are not preceded by a specified pattern without including this pattern (?&lt;!\s)c \lbr (string: ab c abcd) the second c since it's not preceded by a blank the first c

Subgroups are handy in replacements. Using an expression with $ and a number, e. g. $1, you can refer to a particular group. For example, you have a string abcde. A PCRE expression might be (ab|xy)c(d.), i. e. there are two subgroups specified. In a replacement pattern, you can refer to the first group using $1 and the second group using $2. Hence, the replacement pattern $2Z$1 results in deZab.

Anchors and Positions

Expression Represents Example Matches Doesn't Match
^ Beginning of line, alternative: \A ^a. \lbr (string: abcde) ab bc
$ End of line, alternative: \Z $ \lbr (string: abcde) the position right after e any other position
\b beginning and end of word 1) \bd \lbr 2) c\b \lbr (string: abc def) 1) d \lbr 2) c 1) a \lbr 2) f

Searching Using Regular Expressions

Multiple string functions support PCRE expressions by offering the parameter pcre with which you can specify such an expression. FIND and REPLACE statements support regular expressions with the PCRE addition.

The string function match exclusively works with regular expressions. It returns a substring that matches a regular expression within a string. For comparisons, you could also use the predicate function matches that returns true or false if a string matches a given pattern or not.

Syntax examples:

str = `Cathy's black cat on the mat played with Matt.`.

"Determining the position of the first finding
"Here, the parameter occ is 1 by default.
res = find( val = str pcre = `at.` ). "1

"Determining the number of all findings.
"Considers all a characters not followed by t, all at plus att
res = count( val = str  pcre = `at*` ). "6
"Considers all at plus att
res = count( val = str pcre = `at+` ). "4

"Extracting a substring matching a given pattern
str_w_email = `The email address is jon.doe@email.com.`.
res = match( val = str_w_email
             pcre = `\w+(\.\w+)*@(\w+\.)+(\w{2,4})` ). "jon.doe@email.com

"Predicate function matches
"Checking the validitiy of an email address
email = `jon.doe@email.com`.
IF matches( val  = email
            pcre = `\w+(\.\w+)*@(\w+\.)+(\w{2,4})` ).  "true
...
ENDIF.

"Examples with the FIND statement
"Storing submatches in variables.
FIND PCRE `(.*)\son\s(.*)` IN str IGNORING CASE SUBMATCHES a b.
"a: Cathy's black cat, b: the mat played with Matt.

"Determinging the number of letters in a string
FIND ALL OCCURRENCES OF PCRE `[A-Za-z]` IN str MATCH COUNT a. "36

"Searching in an internal table and retrieving line, offset, length information
DATA(itab) = value string_table( ( `Cathy's black cat on the mat played with the friend of Matt.` ) ).
FIND FIRST OCCURRENCE OF PCRE `\bt.` IN TABLE itab
  IGNORING CASE MATCH LINE a MATCH OFFSET b MATCH LENGTH c. "a: 1, b: 21, c: 2

Replacing Using Regular Expressions

To carry out replacement operations using regular expressions both string function replace and REPLACE statements can be used with the pcre parameter or the PCRE addition respectively. Similar to the find function, among others, and FIND statements, the replace function and REPLACE statements offer a variety of parameters or additions respectively to further restrict the area to be replaced. Check the ABAP Keyword Documentation for a more detailed insight. The executable example covers numerous PCRE expressions listed above with the replace function.

Syntax examples:

s = `ab apppc app`.
r = replace( val = s pcre = `p{2,4}` with = `#` ). "ab a#c app
r = replace( val = s pcre = `[^ac]` with = `#` ). "a# apppc app
r = replace( val = s pcre = `[^ac]` with = `#` occ = 0 ). " "a##a###c#a## (all occurences)
r = replace( val = s pcre = `\s` with = `#` occ = 0 ). "ab#apppc#app

"Replacements with subgroups
r = replace( val  = s       pcre = `(.*?)PPP(.*)`
             with = `$2#$1` case = abap_false ). "c app#ab a

"Changing the source field directly with a REPLACE statement
REPLACE PCRE `(.*?)PPP(.*)` IN ss WITH `$2#$1` IGNORING CASE. "c app#ab a

Demonstration Program

The example String Processing demonstrates the syntax variants outlined above in one program.






BAL_S_LOG - Application Log: Log header data   BAL Application Log Documentation  
This documentation is copyright by SAP AG.

Length: 62080 Date: 20240509 Time: 114413     sap01-206 ( 560 ms )