\`...\`) and have the data type `string`.
- Text field literals are enclosed in single quotes (`'...'`) and have the data type `c`.
- The literals can be (but should not according to the [programming guidelines on literals (F1 docu for standard ABAP)](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenliterals_guidl.htm)) used like constants of these types in [operand positions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenoperand_position_glosry.htm). They should be only used for start values when declaring [named data objects](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abennamed_data_object_glosry.htm).
```abap
CLASS zcl_demo_abap DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun.
ENDCLASS.
CLASS zcl_demo_abap IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
out->write( `I am a text string literal` ). "text string literal of type string
out->write( 'I am a text field literal' ). "text field literal of type c
ENDMETHOD.
ENDCLASS.
```
- [Named](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abennamed_data_object_glosry.htm) character-like data types and objects can be declared like other types and objects using [`TYPES`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaptypes.htm), [`DATA`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapdata.htm) [`CONSTANTS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapconstants.htm) and by referring to a character-like data type.
- In addition, character-like data objects can be declared inline with the operators `DATA` and [`FINAL`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfinal_inline.htm).
Syntax examples:
``` abap
"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 str1, "Deriving type from a local data object
str3 TYPE str_type, "Local type
tstmp TYPE timestampl, "DDIC type
char3 TYPE zdemo_abap_flsch-carrid. "Using the type of a DDIC table component
"You may also encounter declarations with type c and the length
"specified in parentheses. This is not recommended, to avoid confusion
"with the use of parentheses in dynamic programming.
DATA char(4) TYPE c.
"Just a TYPE c specification without length means LENGTH 1.
DATA char_len_one TYPE c.
"No type and length specification: TYPE c LENGTH 1 by default
DATA char_no_type_len.
```
## Assigning Values
- When you declare character-like data objects, you can specify start values directly with the `VALUE` addition, e.g. `DATA chars TYPE c LENGTH 3 VALUE 'abc'.`.
- Various ABAP statements assign values. You can do value assignments to data objects using the [assignment operator](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenassignment_operator_glosry.htm "Glossary Entry") `=`.
- As mentioned above, you can declare character-like data objects inline using the operators `DATA` or `FINAL`.
- You can use the operators at many [write positions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwrite_position_glosry.htm "Glossary Entry").
- Unlike the `VALUE` addition of the declaration statements, inline declarations allow you to declare variables for the results of expressions or at other positions where character strings are returned.
- In the case below, a variable specified in parentheses preceded by `DATA` (or `FINAL`) on the left side of the assignment operator automatically derives a data type from the operand on the right. This helps to make your
programs leaner.
Syntax examples:
``` abap
"Data object declarations including default values with VALUE
"Note the chained statement: DATA followed by a colon, listing the data object declarations,
"separated by a comma.
DATA: flag TYPE c LENGTH 1 VALUE 'X',
str1 TYPE string VALUE `Hallo!`.
"Examples for type n
DATA zip_code TYPE n LENGTH 5 VALUE '12345'.
DATA isbn_number TYPE n LENGTH 13 VALUE '1234567890123'.
"Constant; content cannot be changed at runtime
CONSTANTS pi TYPE p LENGTH 8 DECIMALS 14 VALUE '3.14159265358979'.
"More data object declarations
DATA: char1 TYPE c LENGTH 5,
html TYPE string,
str2 LIKE html.
"Value assignments
char1 = 'ab123'.
html = `hallo
`. "Escaping backquotes in text string literals with another one str1 = `This is a backquote: ``.`. "If possible, avoid unnecessary type conversion; in principle, every "convertible type can be specified str2 = 'abc'. "Fixed length string assigned to data object of type string DATA str3 TYPE string VALUE 'X'. "type c length 1 DATA str4 TYPE string VALUE -1. "type i "Inline declarations DATA(char2) = 'abcd'. "Type c length 4 DATA(str5) = `efgh`. "You can use FINAL to create immutable variables. FINAL(final_string) = `zyx`. "Since char2 is of type c length 4 (the length is also derived), "characters are truncated in the following example assignment "Note: In newer ABAP releases, the following statement shows a syntax "warning that the value of the literal (intentionally specified "here like this) is not an admissable value for the target type. char2 = 'ijklmnopq'. "ijkl "Trailing blanks after assigning fixed length to variable length string DATA(char3) = 'ab '. DATA(str6) = `cdefgh`. str6 = char3. "'ab' (trailing blanks are not respected due to conversion rule) ``` - When assigning strings, not only data objects can be placed on the right side. Various expressions and strings can be concatenated using the [concatenation operator](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconcatenation_operator_glosry.htm "Glossary Entry") `&&`. - Alternatively, you can concatenate strings using [string templates](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstring_template_glosry.htm "Glossary Entry"), as described in the *Concatenating Strings* section. ``` abap str5 = str3 && ` ` && str4 && `!`. "X 1-! "Note the output for str4 that includes the conversion of type i to "string above demonstrating a possibly inadvertent specification "of an integer value for str4 that is of type string. ``` ## String Templates - Using string templates, you can construct strings very elegantly from literal text and - which is the primary use case - by including embedded ABAP [expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenexpression_glosry.htm "Glossary Entry") within a pair of delimiters (`|...|`) if these expressions can be converted to `string`. - To embed expressions, you enclose them in curly brackets: `{ ... }`. - Among the expressions that can be specified in the curly brackets are data objects and [functional method calls](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfunctional_method_call_glosry.htm) that have a [return value](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenreturn_value_glosry.htm). The expression result must be convertible to type `string`. > [!NOTE] > - String templates form a [string expression](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstring_expression_glosry.htm "Glossary Entry") that is compiled at runtime. Therefore, a string template that contains only literal text is treated as an expression, which has a performance impact. In such a case, it is preferable to use a text string literal with backquotes. > - It is possible to dynamically specify formatting options. For more information, refer to the [Dynamic Formatting Option Specifications in String Templates](/06_Dynamic_Programming.md#dynamic-formatting-option-specifications-in-string-templates) section of the *Dynamic Programming* cheat sheet. > - Escape `\|{}` in string templates using `\`, i. e. `\\` means `\`. Syntax examples: ``` abap "Value assignment with string templates "The expression must be convertible to a string. A blank (not within the curly brackets) "means a blank in the resulting string. DATA(s1) = |Hallo { cl_abap_context_info=>get_user_technical_name( ) }!|. DATA(s2) = `How are you?`. "Literal text only with backquotes DATA(s3) = |{ s1 } { s2 }|. "Hallo NAME! How are you? "Chaining of string templates using && DATA(s4) = |{ s1 }| && ` ` && |{ s2 }|. "Hallo NAME! How are you? "Selection of possible expressions: "Data objects, as in the examples above DATA(dobj1) = `Hallo`. DATA(dobj2) = '!'. "Hallo! DATA(s5) = |{ dobj1 }{ dobj2 }|. "NOT INITIAL DATA(s6) = |{ COND #( WHEN s5 IS INITIAL THEN `INITIAL` ELSE `NOT INITIAL` ) }|. "Functional method calls, built-in functions "User alias: XXXX... DATA(s7) = |User alias: { cl_abap_context_info=>get_user_alias( ) }|. "Some random number: 39 (example) DATA(s8) = |Some random number: { cl_abap_random_int=>create( seed = cl_abap_random=>seed( ) min = 1 max = 100 )->get_next( ) }|. "Length of string s5: 6 DATA(s9) = |Length of string s5: { strlen( s5 ) }|. "Current UTC time stamp: 2024-01-11 14:27:54.1514090 (example) DATA(s10) = |Current UTC time stamp: { utclong_current( ) }|. "HALLO! DATA(s11) = |{ to_upper( s5 ) }|. "\ | { } DATA(s12) = |\\ \| \{ \}|. ``` ### Control Characters in String Templates - String templates interpret certain character combinations as [control characters](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstring_templates_separators.htm). - For example, `\n` is interpreted as a newline. A new line is started. The following syntax examples demonstrate a selection: ```abap "\n is interpreted as a line feed DATA(s1) = `Hello`. DATA(s2) = `World`. DATA(s3) = |{ s1 }\n{ s2 }\nHow are you\n?|. *Hello *World *How are you *? "Excursion: The CL_ABAP_CHAR_UTILITIES class provides attributes and methods as utilities for string processing. "The following examples demonstrate that attributes that contain control characters can be replaced by "a representation of control characters in a string template. ASSERT cl_abap_char_utilities=>newline = |\n|. ASSERT cl_abap_char_utilities=>horizontal_tab = |\t|. ASSERT cl_abap_char_utilities=>cr_lf = |\r\n|. ``` ### Formatting Options in String Templates - String templates support various formatting options. - The following syntax examples demonstrate a selection. For information about all options, refer to [this topic](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcompute_string_format_options.htm) in the ABAP Keyword Documentation. ```abap *&---------------------------------------------------------------------* *& DATE *&---------------------------------------------------------------------* "Defining the format of a date "The output is just an example and depends on your settings. DATA(d) = |The date is { cl_abap_context_info=>get_system_date( ) DATE = USER }.|. "The date is 01/01/2024. d = |{ cl_abap_context_info=>get_system_date( ) DATE = RAW }|. "20240101 d = |{ cl_abap_context_info=>get_system_date( ) DATE = ISO }|. "2024-01-01 d = |{ cl_abap_context_info=>get_system_date( ) DATE = ENVIRONMENT }|. "01/01/2024 *&---------------------------------------------------------------------* *& TIME *&---------------------------------------------------------------------* "Defining the format of a time "The output is just an example and depends on your settings. DATA(tm) = |The time is { cl_abap_context_info=>get_system_time( ) TIME = ISO }.|. "The time is 14:37:24. tm = |{ cl_abap_context_info=>get_system_time( ) TIME = RAW }|. "143724 tm = |{ cl_abap_context_info=>get_system_time( ) TIME = USER }|. "14:37:24 tm = |{ cl_abap_context_info=>get_system_time( ) TIME = ENVIRONMENT }|. "14:37:24 *&---------------------------------------------------------------------* *& TIMESTAMP *&---------------------------------------------------------------------* "Defining the format of a time stamp "The output is just an example and depends on your settings. DATA(ts) = |{ utclong_current( ) TIMESTAMP = SPACE }|. "2024-01-01 14:39:50.4069170 ts = |{ utclong_current( ) TIMESTAMP = ISO }|. "2024-01-01T14:39:50,4071110 ts = |{ utclong_current( ) TIMESTAMP = USER }|. "01/01/2024 14:39:50.4072010 ts = |{ utclong_current( ) TIMESTAMP = ENVIRONMENT }|. "01/01/2024 14:39:50.4073230 ts = |{ utclong_current( ) }|. "2024-01-01 14:39:50.4074060 *&---------------------------------------------------------------------* *& TIMEZONE *&---------------------------------------------------------------------* "Defining the format of a time stamp using the rules for time zones DATA(tz) = |{ utclong_current( ) TIMEZONE = 'UTC' }|. "2024-12-30 14:43:20.6534640 tz = |{ utclong_current( ) TIMEZONE = 'CET' COUNTRY = 'DE ' }|. "30.12.2024 15:43:20,6536320 tz = |{ utclong_current( ) TIMEZONE = 'EST' COUNTRY = 'US ' }|. "12/30/2024 09:43:20.6889180 AM *&---------------------------------------------------------------------* *& CASE *&---------------------------------------------------------------------* "Lowercase and uppercase DATA s1 TYPE string. DATA s2 TYPE string. s1 = `AbCdEfG`. s2 = |{ s1 CASE = LOWER }|. "abcdefg s2 = |{ s1 CASE = UPPER }|. "ABCDEFG *&---------------------------------------------------------------------* *& WIDTH/ALIGN *&---------------------------------------------------------------------* s1 = `##`. s2 = |{ s1 WIDTH = 10 ALIGN = LEFT }<---|. "'## <---' s2 = |{ s1 WIDTH = 10 ALIGN = CENTER }<---|. "' ## <---' *&---------------------------------------------------------------------* *& PAD *&---------------------------------------------------------------------* "Used to pad any surplus places in the result with the specified character. s2 = |{ s1 WIDTH = 10 ALIGN = RIGHT PAD = `.` }<---|. "'........##<---' *&---------------------------------------------------------------------* *& DECIMALS *&---------------------------------------------------------------------* s1 = |{ CONV decfloat34( - 1 / 3 ) DECIMALS = 3 }|. "'-0.333' *&---------------------------------------------------------------------* *& SIGN *&---------------------------------------------------------------------* "Defining the format of the +/- sign when the string represented "by the embedded expression represents a numeric value "- left without space, no + s1 = |{ +1 SIGN = LEFT }|. "1 "- and + left without space s1 = |{ 1 SIGN = LEFTPLUS }|. "+1 "- left without space, blank left for + s1 = |{ 1 SIGN = LEFTSPACE }|. " 1 "- right without space, no + s1 = |{ -1 SIGN = RIGHT }|. "1- "- and + right without space s1 = |{ 1 SIGN = RIGHTPLUS }|. "1+ "- left without space, blank right for + s1 = |{ +1 SIGN = RIGHTSPACE }|. "1 *&---------------------------------------------------------------------* *& ZERO *&---------------------------------------------------------------------* "Defining the format of the numeric value zero. "Only to be specified if the embedded expression has a numeric data type. s1 = |'{ 0 ZERO = NO }' and '{ 0 ZERO = YES }'|. "'' and '0' *&---------------------------------------------------------------------* *& XSD *&---------------------------------------------------------------------* "Formatting is applied to an embedded expression (elementary data types) in asXML format that is "assigned to its data type. Check the information in the ABAP Keyword Documentation about the asXML "mapping of elementary ABAP types. DATA xstr TYPE xstring VALUE `41424150`. DATA dat type d value '20240101'. DATA tim type t value '123456'. DATA(utc) = utclong_current( ). "e.g. 2024-01-01 13:51:38.5708800 s1 = |{ xstr XSD = YES }|. "QUJBUA== s1 = |{ dat XSD = YES }|. "2024-01-01 s1 = |{ tim XSD = YES }|. "12:34:56 s1 = |{ utc XSD = YES }|. "2024-01-01T13:51:38.57088Z *&---------------------------------------------------------------------* *& STYLE *&---------------------------------------------------------------------* "Defining the style of decimal floating point numbers; "see the details in the ABAP Keyword Documentation. DATA(dcfl34) = CONV decfloat34( '-123.45600' ). s1 = |{ dcfl34 }|. "-123.456 "Creates the predefined format s1 = |{ dcfl34 STYLE = SIMPLE }|. "-123.456 "+/- added to the right, removes trailing zeros s1 = |{ dcfl34 STYLE = SIGN_AS_POSTFIX }|. "123.456- "Retains trailing zeros s1 = |{ dcfl34 STYLE = SCALE_PRESERVING }|. "-123.45600 "Scientific notation; at least a two digit exponent with a plus/minus sign s1 = |{ dcfl34 STYLE = SCIENTIFIC }|. "-1.23456E+02 "Scientific notation; only one integer digit with the value 0 s1 = |{ dcfl34 STYLE = SCIENTIFIC_WITH_LEADING_ZERO }|. "-0.123456E+03 "Scientific notation; exponent has 3 digits for decfloat16 and 4 digits for decfloat34 s1 = |{ dcfl34 STYLE = SCALE_PRESERVING_SCIENTIFIC }|. "-1.2345600E+0002 "Technical format s1 = |{ dcfl34 STYLE = ENGINEERING }|. "-123.456E+00 *&---------------------------------------------------------------------* *& ALPHA *&---------------------------------------------------------------------* "Adds or removes leading zeros from strings of digits; the data type "must be string, c, or n "Adding leading zeros "Additionally specifying WIDTH "Note: The specified length is only used if it is greater than "the length of provided string (without leading zeros) s1 = |{ '1234' ALPHA = IN WIDTH = 10 }|. "0000001234 s1 = |{ '00000000000000000000000012' ALPHA = IN WIDTH = 10 }|. "0000000012 "Fixed-length string provided, WIDTH not specified s1 = |{ ' 12' ALPHA = IN }|. "00012 "Removing leading zeros s1 = |{ '00001234' ALPHA = OUT }|. "1234 "Do not apply formatting s1 = |{ '00001234' ALPHA = RAW }|. "00001234 ``` ## Determining the Length of Strings - To determine the length of a string, you can use the string function [`strlen`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlength_functions.htm). - Note that the result depends on the type of the string, i. e. the result for a data object of type `string` includes trailing blanks. A fixed-length string does not include them. - To exclude trailing blanks in all cases, regardless of the data type, you can use the built-in [`numofchar`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlength_functions.htm) function. - [`xstrlen`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendescriptive_functions_binary.htm) returns the number of bytes of a byte-like argument. Syntax examples: ``` abap "strlen DATA(len_c_a) = strlen( 'abc ' ). "3 DATA(len_c_b) = strlen( ' abc ' ). "6 DATA(len_str_a) = strlen( `abc ` ). "6 DATA(len_str_b) = strlen( ` abc ` ). "9 "numofchar len_c_a = numofchar( 'abc ' ). "3 len_c_b = numofchar( ' abc ' ). "6 len_str_a = numofchar( `abc ` ). "3 len_str_a = numofchar( ` abc ` ). "6 DATA(xstr) = CONV xstring( `480065006C006C006F00200077006F0072006C0064002100` ). DATA(len_xstr) = xstrlen( xstr ). "24 ``` ## Concatenating Strings - Two or more strings can be concatenated using the concatenation operator `&&` and string templates. Alternatively, you can use [`CONCATENATE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapconcatenate.htm) statements. - It is also possible to concatenate lines from internal tables with character-like line type into a string to avoid a loop. - A more modern way is to use the string function [`concat_lines_of`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconcatenation_functions.htm). Syntax examples: ``` abap "&& and string template "abcd DATA(s1) = `ab` && `cd`. "efgh abcd DATA(s2) = `ef` && `gh` && ` ` && s1. "abcd. efgh abcd! DATA(s3) = |{ s1 }. { s2 }!|. "CONCATENATE statements "uvwxyz DATA(s4) = `uvw`. DATA(s5) = `xyz`. CONCATENATE s4 s5 INTO s3. "Multiple data objects and target declared inline "uvw xyz CONCATENATE s4 ` ` s5 INTO DATA(s6). "abcdefgh abcduvwxyz CONCATENATE s1 s2 s4 s5 INTO DATA(s7). "You can also add a separation sign using the addition SEPARATED BY "uvw xyz CONCATENATE s4 s5 INTO DATA(s8) SEPARATED BY ` `. "uvw#xyz CONCATENATE s4 s5 INTO DATA(s9) 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 DATA(ch) RESPECTING BLANKS. "'a b c ' "Concatenating lines of internal tables with character-like line type into a string DATA(itab) = VALUE string_table( ( `abc` ) ( `def` ) ( `ghi` ) ). "abcdefghi CONCATENATE LINES OF itab INTO DATA(conc_tab1). "abc def ghi CONCATENATE LINES OF itab INTO DATA(conc_tab2) SEPARATED BY ` `. "abc,def,ghi CONCATENATE LINES OF itab INTO DATA(conc_tab3) SEPARATED BY `,`. "Using concat_lines_of s1 = concat_lines_of( table = itab ). "Without separator s1 = concat_lines_of( table = itab sep = ` ` ). "With separator ``` ### Concatenation Assignment Operator &&= - You can use the concatenation assignment operator `&&=` to concatenate strings in an assignment. ```abap "This assignment using the concatenation assignment operator ... a &&= b. "... has the same effect as the following. a = a && b. ``` - `a` can be variables and writable expressions (such as certain constructor expressions, e.g. `CAST`, or table expressions). It cannot be an inline declaration. - `b` can be character-like data objects, constructor expressions, string expressions (such as string templates), table expressions or functions ```abap DATA a1 TYPE string VALUE `a`. DATA a2 TYPE string VALUE `a`. DATA b TYPE string VALUE `b`. a1 &&= b. a2 = a2 && b. ASSERT a1 = a2. *&---------------------------------------------------------------------* *& Left-hand data object *&---------------------------------------------------------------------* "The left-hand data object can also be represented by a writable expression "Constructor expression with CAST DATA ref TYPE REF TO data. ref = NEW string( `h` ). CAST string( ref )->* &&= `ello`. "hello "Table expression DATA(str_table) = VALUE string_table( ( `AB` ) ). str_table[ 1 ] &&= `AP`. "ABAP *&---------------------------------------------------------------------* *& Right-hand data object *&---------------------------------------------------------------------* "The right-hand data object can be represented by a character-like data object, as "shown in the previous examples, or whose content can be converted, as well as ... "... constructor expressions DATA txt TYPE string. txt = `abc`. "abcdef txt &&= CONV string( 'def' ). txt = `ghi`. "The REDUCE operator itself uses the concatenation assignment operator "in the assignment of NEXT. "ghijkl txt &&= REDUCE string( INIT str = VALUE #( ) FOR line IN VALUE string_table( ( `j` ) ( `k` ) ( `l` ) ) NEXT str &&= line ). txt = `mno`. "mnopqr txt &&= COND #( WHEN txt = `mno` THEN `pqr` ELSE `stu` ). "... string expressions such as string templates CLEAR txt. DO 5 TIMES. "1, 2, 3, 4, 5 txt &&= |{ COND #( WHEN sy-index <> 1 THEN `, ` ) }{ sy-index }|. ENDDO. "... table expressions DATA(tab) = VALUE string_table( ( `v` ) ( `w` ) ( `x` ) ). txt = `a`. "av txt &&= tab[ 1 ]. "Content of tab[ 2 ]: wx tab[ 2 ] &&= tab[ 3 ]. "... functions txt = `a`. "abbbbb txt &&= repeat( val = `b` occ = 5 ). DATA(strtab) = VALUE string_table( ( `b` ) ( `c` ) ( `d` ) ). txt = `a`. "abcd txt &&= concat_lines_of( table = strtab ). ``` ### Literal Operator The [literal operator](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenliteral_operator_glosry.htm "Glossary Entry") `&` combines [text string literals](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentext_string_literal_glosry.htm "Glossary Entry"), however, with [significant differences](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenliteral_operator.htm) to `&&`, which the code snippet addresses. ```abap "Literal operator "Used to combine character literals of the same type into a single character literal DATA(abap) = 'AB' & 'AP'. "Note an upper limit of 255 characters "If you remove the comment, which results in a combined character literal "of 256 characters, a syntax error is displayed. DATA(c_limit_255) = '##################################################' & "50 x # '##################################################' & '##################################################' & '##################################################' & '##################################################' & '#####' "& '#' . "Trailing blanks are respected DATA(char_with_blanks) = 'AB' & 'AP' & ' '. "Using RTTI to get type information, retrieving the output length of the combined literal "15 DATA(output_length) = CAST cl_abap_elemdescr( cl_abap_typedescr=>describe_by_data( char_with_blanks ) )->output_length. DATA(ch1) = 'AB'. DATA(ch2) = 'AP'. "Not possible as the operands are not character literals but data objects "DATA(combined_ch) = ch1 & ch2. "Not to be confused with the concatenation operator && to concatenate "character-like operands; at runtime, any number of character-like operands "are possible "The result in the example is of type string. DATA(combined_ch_with_conc_op) = ch1 && ch2. "Concatenation similar to the example above "As the result is of type string using the concatenation operator, the "trailing blanks are not respected. DATA(char_with_blanks_conc_op) = 'AB' && 'AP' && ' '. "4 DATA(len1) = strlen( char_with_blanks_conc_op ). "4 DATA(len2) = numofchar( char_with_blanks_conc_op ). ``` ## Splitting Strings - You can use [`SPLIT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapsplit.htm) statements to split strings in multiple segments. - The result of the split can be stored in separate data objects or internal tables that have a character-like line type. - Note that if the number of specified targets is less than the number of segments returned by the split, the last target receives the remaining unsplit segments. If more targets are specified, the targets that do not receive a segment are initialized. - Therefore, 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 particular segment, you can use the string function [`segment`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensegment_functions.htm). Syntax examples: ``` abap DATA(s1) = `Hallo,world,123`. DATA: s2 TYPE string, s3 TYPE string, s4 TYPE string. SPLIT s1 AT `,` INTO s2 s3 s4. "s2 = Hallo / s3 = world / s4 = 123 "Less data objects than possible splittings SPLIT s1 AT `,` INTO s2 s3. "s2 = Hallo / s3 = world,123 "Splitting into internal table DATA itab TYPE TABLE OF string. SPLIT s1 AT ',' INTO TABLE itab. "Strings are added to itab in individual lines without comma "String function segment returning the occurrence of a segment "index parameter: number of segment s2 = segment( val = s1 index = 2 sep = `,` ). "world "SPLIT statement specifying a colon after INTO DATA(some_text) = `Lorem ipsum dolor sit amet, consectetur adipiscing elit`. SPLIT some_text AT ` ` INTO: DATA(str1) DATA(str2) DATA(str3) DATA(str4), TABLE DATA(tab). "Result "str1: Lorem "str2: ipsum "str3: dolor "str4: sit amet, consectetur adipiscing elit "tab: *Lorem *ipsum *dolor *sit *amet, *consectetur *adipiscing *elit ``` ## Modifying Strings ### Transforming to Lowercase and Uppercase - The string functions [`to_lower`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencase_functions.htm) and [`to_upper`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencase_functions.htm) transform characters of a string to either lowercase or uppercase and store the result in a target variable. - If you want to apply the transformation to the source directly, you can use [`TRANSLATE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaptranslate.htm) statements. Syntax examples: ``` abap "String functions DATA(s1) = to_upper( `abap` ). "ABAP s1 = to_lower( `SOME_FILE.Txt` ). "some_file.txt "TRANSLATE statements s1 = `Hallo`. TRANSLATE s1 TO UPPER CASE. "HALLO TRANSLATE s1 TO LOWER CASE. "hallo "For the transformation of the source directly, you can "also specify an existing, changeable data object as "the source in a simple assignment as follows. s1 = to_upper( s1 ). ``` ### Shifting Content - You can shift content within a string to a specific position on the left or right of a string. [`SHIFT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapshift.htm) statements have various additions for specific use cases. - In a more modern way, you can use the string functions [`shift_left`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenshift_functions.htm) and [`shift_right`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenshift_functions.htm), which store the result in a variable. - These functions provide additional functionality. The `sub` parameter can be used to specify a substring. All substrings in the string that match the value specified in `sub` on either the left or right side of the string are removed. Syntax examples: ``` abap "SHIFT statements "Note that all results below refer to s1 = `hallo`. DATA(s1) = `hallo`. "Type string SHIFT s1. "No addition; string shifted one place to the left: allo SHIFT s1 BY 2 PLACES. "Without direction, left by default: llo SHIFT s1 BY 3 PLACES RIGHT. "With direction, variable length strings are extended: ' hallo' "Note that all results below refer to ch4 = 'hallo'. DATA(ch4) = 'hallo'. "Type c length 5 SHIFT ch4 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 ch4 BY 3 PLACES LEFT CIRCULAR. "lohal SHIFT ch4 UP TO `ll`. "Shift characters up to a specific character set: llo "Deleting leading and trailing characters DATA(s2) = ` hallo `. DATA(s3) = s2. SHIFT s2 LEFT DELETING LEADING ` `. "'hallo ' SHIFT s3 RIGHT DELETING TRAILING ` `. "' hallo' (length is kept) "Removing trailing blanks in strings without leading blanks; "you can use the following sequence of statements DATA(s4) = `hallo `. DATA(s5) = s4. SHIFT s4 RIGHT DELETING TRAILING ` `. "' hallo' SHIFT s4 LEFT DELETING LEADING ` `. "'hallo' "To remove trailing blanks, you can also use the following method of the "cl_abap_string_utilities class. cl_abap_string_utilities=>del_trailing_blanks( CHANGING str = s5 ). ASSERT s4 = s5. "Note the c2str_preserving_blanks method for preserving trailing blanks "when assigning text fields to data objects of type string. "String functions with parameters s1 = `hallo`. s2 = shift_left( val = s1 places = 3 ). "lo s2 = shift_left( val = s1 circular = 2 ). "lloha "Note that shift_right does not extend a variable length string. s2 = shift_right( val = s1 places = 3 ). "ha s2 = shift_right( val = `abc ` sub = ` ` ). "'abc' s2 = shift_right( val = `abc ` ). "'abc' (same result as above) ``` ### Condensing Strings - You can use [`CONDENSE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcondense.htm) statements or the string function [`condense`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencondense_functions.htm) to remove blanks from strings. - The advantage of using the string function is that you can specify any character to remove, not just blanks. Syntax examples: ``` abap "CONDENSE statements DATA(s1) = ` ab cd `. DATA(s2) = ` ef gh ij `. DATA(s3) = ` kl mn op `. CONDENSE s1. "Trailing and leading blanks are removed: 'ab cd' CONDENSE s2. "It also replaces sequences of multiple blanks with a single blank: 'ef gh ij' CONDENSE s3 NO-GAPS. "Removes all blanks: 'klmnop' "String function condense s1 = ` ab cd `. "No parameters specified, i. e. their default values are provided. "Works like CONDENSE statement without the NO-GAPS addition. s2 = condense( s1 ). "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. s2 = condense( val = s1 from = `` ). "ab cd "Parameter to specified with an initial string. No other parameters. "Works like CONDENSE statement with the NO-GAPS addition. s2 = condense( val = s1 to = `` ). "abcd "Parameter del specifies the leading/trailing characters to be removed. s2 = 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 s2 = condense( val = ` Rock'xxx'Roller` del = `re ` from = `x` to = `n` ). "Rock'n'Roll ``` ### Reversing Strings The string function [`reverse`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenreverse_functions.htm) reverses a string: ``` abap "Result: 'abap' DATA(s1) = reverse( `paba` ). ``` ### Inserting Substrings into Strings - The string function [`insert`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninsert_functions.htm) inserts a substring at any position within a given string. You can use various parameters to construct the string you want: - `val`: Original string. - `sub`: Substring. - `off`: Optionally sets the offset, i.e. the position where the substring should be added. 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`). - Inserting substrings can also be accomplished using the string function `replace` or `REPLACE` statements, which are are covered below. Syntax examples: ``` abap "Result: 'abcdefghi' DATA(s1) = insert( val = `abcghi` sub = `def` off = 3 ). "Result: 'defabcghi' s1 = insert( val = `abcghi` sub = `def` ). ``` ### Overlaying Content You can use [`OVERLAY`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapoverlay.htm) statements to replace characters in one variable with characters in another variable that are in the same place there. Syntax examples: ``` abap DATA(incl) = '==============================CP'. DATA(cl_name) = 'CL_SOME_CLASS '. "Addition ONLY is not specified: All blanks are replaced OVERLAY cl_name WITH incl. "cl_name: CL_SOME_CLASS=================CP DATA(txt1) = 'a.b.c.a.b.c.A'. DATA(txt2) = 'z.x.y.Z.x.y.z'. "Addition ONLY is specified: All characters that are specified after ONLY and that "occur in the operand are replaced. Note that this is case-sensitive. OVERLAY txt1 WITH txt2 ONLY 'ab'. "txt1: z.x.c.Z.x.c.A ``` ## Accessing and Processing Substrings - The string function [`substring`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubstring_functions.htm) allows you to specify the position (parameter `off`) and the length (`len`) of a substring to 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. - If `len` is not specified, the rest of the remaining characters is respected. 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 can also access substrings by specifying certain data objects in certain positions using the data object name (field symbols and dereferenced data reference variables are also possible) and the length in parentheses. - Additionally, you can specify the offset using the `+` character after a variable. - Specifying the length with an asterisk (`*`) means that the rest of the remaining string is respected. - This syntax option even allows write access to substrings for fixed-length strings. Read access is possible for both fixed-length and variable-length strings. - However, this syntax can be confused with the use of tokens in the context of dynamic programming. - There are other string functions available for dealing with substrings, such as [`substring_after`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubstring_functions.htm), [`substring_before`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubstring_functions.htm), [`substring_from`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubstring_functions.htm) and [`substring_to`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubstring_functions.htm). - These functions offer more options in terms of parameters, such as the use of [PCRE regular expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenpcre_regex_glosry.htm "Glossary Entry"). - As also shown further down, using the built-in function `match`, you can extract substrings matching a given pattern. Syntax examples: ``` abap DATA(s1) = `Lorem ipsum dolor sit amet`. "Type string "Extracting substring starting at a specific position "'len' not specified means the rest of the remaining characters is "respected DATA(s2) = substring( val = s1 off = 6 ). "ipsum dolor sit amet "Extracting substring with a specific length "'off' is not specified and has the default value 0. s2 = substring( val = s1 len = 5 ). "Lorem "Specifying both off and len parameters s2 = substring( val = s1 off = 6 len = 5 ). "ipsum DATA(txt) = 'Lorem ipsum dolor sit amet'. "Type c "Offset and length specification for substring access "Length specification only in parentheses, no offset "specification means starting from 0 DATA(ch6) = txt(5). "Lorem "Offset specification using the + sign after a variable "The following example corresponds to the previous one "(offset 0 explicitly specified) DATA(ch7) = txt+0(5). "Lorem DATA(ch8) = txt+6(5). "ipsum "* means respecting the rest of the remaining string DATA(ch9) = txt+12(*). "dolor sit amet "Using the syntax in various contexts, e.g. modifying the "text field CLEAR txt+11(*). "Lorem ipsum txt = 'Lorem ipsum dolor sit amet'. txt(5) = 'Hallo'. "Hallo ipsum dolor sit amet txt+7(3) = '###'. "Hallo i###m dolor sit amet "Field symbol TYPES abc TYPE c LENGTH 26. FIELD-SYMBOLSHallo\n
Ciao!
Salut.
|. DATA(html_b) = html_a. REPLACE ALL OCCURRENCES OF PCRE `()(.*?)(<\/p>)` IN html_a WITH `$1Hi$3`. *
Hallo *
Hi
Hi
"Regular expression: any character or a new line with zero or more repretitions REPLACE ALL OCCURRENCES OF PCRE `()(.|\n)*?(<\/p>)` IN html_b WITH `$1Hi$3`. *
Hi
Hi
Hi
``` ## More String Functions As also covered in the [Built-In Functions](24_Builtin_Functions.md) cheat sheet, the following sections show more string functions available. ### Checking the Similarity of Strings - [`distance`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendistance_functions.htm) returns the Levenshtein distance between two strings, which reflects their similarity. - Unlike other string functions, the return value has the type `i`. - Optional addition `max`: Positive integer. The calculation of the Levenshtein distance will stop if the calculated value is greater than this integer. ```abap DATA(str_to_check) = `abap`. DATA(dist1) = distance( val1 = str_to_check val2 = `abap` ). "0 DATA(dist2) = distance( val1 = str_to_check val2 = `axbap` ). "1 DATA(dist3) = distance( val1 = str_to_check val2 = `yabyyapy` ). "4 DATA(dist4) = distance( val1 = str_to_check val2 = `zabapzzzzzzzzzzzz` max = 5 ). "5 "If the value of max is 0 or less, an exception is raised. TRY. DATA(dist5) = distance( val1 = str_to_check val2 = `#ab#ap#` max = 0 ). CATCH cx_sy_strg_par_val. ... ENDTRY. ``` ### Repeating Strings - [`repeat`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrepeat_functions.htm) returns a string that contains the content of a specified string for parameter `val` as many times as specified in the parameter `occ`. - An empty string is returned when `occ` has the value 0 or `val` is empty. ```abap DATA(repeat1) = repeat( val = `abap` occ = 5 ). "abapabapabapabapabap DATA(repeat2) = |#{ repeat( val = ` ` occ = 10 ) }#|. "# # DATA(repeat3) = COND #( WHEN repeat( val = `a` occ = 0 ) = `` THEN `Y` ELSE `Z` ). "Y (initial value returned) "If occ has a negative value, an exception is raised. TRY. DATA(repeat4) = repeat( val = `X` occ = -3 ). CATCH cx_sy_strg_par_val. ... ENDTRY. ``` ### Returning the Smallest/Biggest of a Set of Character-Like Arguments - [`cmin/cmax`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencmax_cmin_functions.htm) returns a string that contains the content of the smallest or biggest of a set of character-like arguments - 'Set' means at least two arguments and a maximum of nine argeuments are passed (`valn` operators) for comparison. - The comparison is made from left to right, and the first different character found determines the smaller or bigger argument. ```abap DATA(min) = cmin( val1 = `zzzzzzz` val2 = `zzazzzzzzzz` "smallest argument val3 = `zzzzabc` ). DATA(max) = cmax( val1 = `abcdef` "biggest argument val2 = `aaghij` val3 = `aaaaklmn` val4 = `aaaaaaopqrs` val5 = `aaaaaaaaaatuvwxy` val6 = `aaaaaaaaaaaaaz` ). ``` ### Escaping Special Characters - [`escape`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenescape_functions.htm) returns a string that is provided for the `val` parameter by escaping special characters according to the specification in the `format` parameter. - Suitable values for the `format` parameter (which expects a data object of type `i`) are available in the `CL_ABAP_FORMAT` class (the constants starting with `E_`). - Special rules apply to different contexts, such as URLS and JSON. Also note the prevention of Cross Site Scripting (XSS) attacks on web applications. For more information, refer to the [documentation](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenescape_functions.htm). ```abap "Context: URLs DATA(esc1) = escape( val = '...test: 5@8...' format = cl_abap_format=>e_url_full ). "...test%3A%205%408... "Context: JSON DATA(esc2) = escape( val = 'some "test" json \ with backslash and double quotes' format = cl_abap_format=>e_json_string ). "some \"test\" json \\ with backslash and double quotes "Context: String templates DATA(esc3) = escape( val = 'Special characters in string templates: |, \, {, }' format = cl_abap_format=>e_string_tpl ). "Special characters in string templates: \|, \\, \{, \} "Invalid value for the format parameter TRY. DATA(esc4) = escape( val = 'This will raise an exception due to an invalid format value.' format = 123 ). CATCH cx_sy_strg_par_val. ENDTRY. ``` ## Excursions ### Comparison Operators for Character-Like Data Types in a Nutshell The comparison operators have already been covered in different sections above. This is a summary of the operators.| Comparison Operator | Details | Example |
|---|---|---|
CA |
Contains any To determine whether any character of a given character set is contained in a string. Note: The search is case-sensitive. sy-fdpos contains the offset of the first character found, while 0 stands for the very first position. If nothing is found, sy-fdpos contains the length of the string. |
```abap DATA(s1) = `cheers`. IF s1 CA `aeiou`. ... "true; sy-fdpos: 2 IF s1 CA `xy`. ... "false; sy-fdpos: 6 ``` |
NA |
Contains not any To determine whether any character of a given character set is not contained in a string. See the note above. |
```abap DATA(s2) = `Hallo`. IF s2 NA `bcdeh`. ... "true; sy-fdpos: 5 IF s2 NA `bcdeH`. ... "false; sy-fdpos: 0 ``` |
CO |
Contains only To determine whether a string contains only a certain set of characters. See the note above. |
```abap DATA(s3) = `abcd`. IF s3 CO `abcd`. ... "true; sy-fdpos: 4 IF s3 CO `abCd`. ... "false; sy-fdpos: 2 ``` |
CN |
Contains not only To determine whether a string does not only contain a certain set of characters, i.e. whether a string contains characters other than those in the character set. See the note above. |
```abap DATA(s4) = `abap`. IF s4 CN `ab`. ... "true; sy-fdpos: 3 IF s4 CN `abp`. ... "false; sy-fdpos: 4 ``` |
CS |
Contains string For simple substring searches and determining whether a string contains a substring. Note: The search is not case-sensitive. sy-fdpos contains the offset of the first substring found. If it is not found, sy-fdpos contains the length of the string searched. |
```abap DATA(s5) = `Lorem ipsum dolor sit amet.`. IF s5 CS `or`. ... "true; sy-fdpos: 1 IF s5 CS `zz`. ... "false; sy-fdpos: 27 ``` |
NS |
Contains no string To determine whether a substring is not contained in a string. See the note for CS. |
```abap DATA(s6) = `some test string`. IF s6 NS `tests`. ... "true; sy-fdpos: 16 IF s6 NS `TEST`. ... "false; sy-fdpos: 5 ``` |
CP |
Conforms to pattern For simple pattern searches and determining whether a set of characters is contained in a string that matches a particular pattern. You can use the following special characters as patterns:
#. If a pattern is found, sy-fdpos returns the offset of the first occurrence. Otherwise, it contains the length of the string searched.
|
```abap DATA(s7) = `abc_def_ghi`. "Pattern: f is preceded by any character sequence, must be followed "by '_' and then followed by any character sequence IF s7 CP `*f#_*`. ... "true; sy-fdpos: 6 "Pattern: i is preceded by any character sequence, must be followed "by any character or a blank IF s7 CP `*i+`. ... "false; sy-fdpos: 11 ``` |
NP |
Does not conform to pattern Negation of CP. See the previous notes. |
```abap DATA(s8) = `abcDEFghi`. "Pattern: c is preceded by any character sequence, must be followed "by a small letter d, and then followed by any character sequence IF s8 NP `*c#d*`. ... "true; sy-fdpos: 9 "Pattern: c is preceded by any character sequence, must be followed "by a capital letter D, and then followed by any character sequence IF s8 NP `*c#D*`. ... "false; sy-fdpos: 2 ``` |
string).
``` abap
DATA(string) = `ABAP `.
"Removing trailing blanks
cl_abap_string_utilities=>del_trailing_blanks( CHANGING str = string ).
"`ABAP`
"Preserving trailing blanks when assigning text fields to data objects of
"type string
DATA(chars) = 'ABAP '.
cl_abap_string_utilities=>c2str_preserving_blanks( EXPORTING source = chars
IMPORTING dest = DATA(str_w_blanks) ).
"`ABAP `
DATA(str_no_blanks) = CONV string( chars ).
"`ABAP`
```
- `XCO_CP`: The Extension Components Library (XCO) library provides [released APIs](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenreleased_api_glosry.htm) and offers various development utilities. Find more information [here](https://help.sap.com/docs/btp/sap-business-technology-platform/overview-of-xco-modules). The following code snippet demonstrates several methods of the class that deal with string processing.
```abap
"--------- Extracting a substring from a string ---------
DATA(some_string) = `abcdefghijklmnopqrstuvwxyz`.
"Creating an encapsulation of a string using XCO
DATA(str) = xco_cp=>string( some_string ).
"Using the FROM and TO methods, you can determine
"the character position. Note that the value includes the
"character at the position specified.
"The character index pattern for the example string above
"is (the string has 26 characters in total):
"a = 1, b = 2, c = 3 ... z = 26
"a = -26, b = -25, c = -24 ... z = -1
"Providing a value that is out of bounds means that
"the first (or the last) character of the string is used
"by default.
"Note: When combining FROM and TO, e.g. with method
"chaining ...->from( ...)->to( ... ), note that another
"instance is created with the first 'from', and another
"character index pattern is created based on the new
"and adjusted string value.
"bcdefghijklmnopqrstuvwxyz
DATA(sub1) = str->from( 2 )->value.
"defghijklmnopqrstuvwxyz
DATA(sub2) = str->from( -23 )->value.
"vwxyz
DATA(sub3) = str->from( -5 )->value.
"abcde
DATA(sub4) = str->to( 5 )->value.
"ab
DATA(sub5) = str->to( -25 )->value.
"Result of 1st 'from' method call: bcdefghijklmnopqrstuvwxyz
"Based on this result, the 'to' method call is
"applied.
"bcdefg
DATA(sub6) = str->from( 2 )->to( 6 )->value.
"Result of 1st 'to' method call: abcdefghijklmnopq
"Based on this result, the 'from' method call is
"applied.
"defghijklmnopq
DATA(sub7) = str->to( -10 )->from( 4 )->value.
"Values that are out of bounds.
"In the example, the first and last character of the
"string are used.
"abcdefghijklmnopqrstuvwxyz
DATA(sub8) = str->from( 0 )->to( 100 )->value.
"--------- Splitting and joining ---------
"Splitting a string into a string table
DATA(str_table) = xco_cp=>string( `Hello.World.ABAP` )->split( `.` )->value.
"Hello
"World
"ABAP
"Concatenating a string table into a string; specifying a delimiter
str_table = VALUE #( ( `a` ) ( `b` ) ( `c` ) ).
"a, b, c
DATA(conc_str1) = xco_cp=>strings( str_table )->join( `, ` )->value.
"Concatenating a string table into a string; specifying a delimiter and
"reversing the table order
"c / b / a
DATA(conc_str2) = xco_cp=>strings( str_table )->reverse( )->join( ` / ` )->value.
"--------- Prepending and appending strings ---------
DATA(name) = xco_cp=>string( `Max Mustermann` ).
"Max Mustermann, Some Street 1, 12345 Someplace
DATA(address) = name->append( `, Some Street 1, 12345 Someplace` )->value.
"Mr. Max Mustermann
DATA(title) = name->prepend( `Mr. ` )->value.
"--------- Transforming to lowercase and uppercase ---------
"ABAP
DATA(to_upper) = xco_cp=>string( `abap` )->to_upper_case( )->value.
"hallo world
DATA(to_lower) = xco_cp=>string( `HALLO WORLD` )->to_lower_case( )->value.
"--------- Checking if a string starts/ends with a specific string ---------
DATA check TYPE string.
DATA(str_check) = xco_cp=>string( `Max Mustermann` ).
"yes
IF str_check->ends_with( `mann` ).
check = `yes`.
ELSE.
check = `no`.
ENDIF.
"no
IF str_check->starts_with( `John` ).
check = `yes`.
ELSE.
check = `no`.
ENDIF.
"--------- Converting strings to xstrings using a codepage ---------
"536F6D6520737472696E67
DATA(xstr) = xco_cp=>string( `Some string` )->as_xstring( xco_cp_character=>code_page->utf_8 )->value.
"--------- Camel case compositions and decompositions with split and join operations ---------
"Pascal case is also possible
"someValue
DATA(comp) = xco_cp=>string( `some_value` )->split( `_` )->compose( xco_cp_string=>composition->camel_case )->value.
"Camel case decomposition
"some_value
DATA(decomp) = xco_cp=>string( `someValue` )->decompose( xco_cp_string=>decomposition->camel_case )->join( `_` )->value.
"--------- Matching string against regular expression ---------
DATA match TYPE string.
"yes
IF xco_cp=>string( ` 1` )->matches( `\s\d` ).
match = 'yes'.
ELSE.
match = 'no'.
ENDIF.
"no
IF xco_cp=>string( ` X` )->matches( `\s\d` ).
match = 'yes'.
ELSE.
match = 'no'.
ENDIF.
```
### Byte String Processing
#### Determining the Length of xstrings
The built-in function [`xstrlen`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendescriptive_functions_binary.htm) returns the number of bytes of a byte-like argument.
``` abap
DATA(hi) = `Hello world`.
"48656C6C6F20776F726C64
DATA(conv_xstring) = cl_abap_conv_codepage=>create_out( codepage = `UTF-8` )->convert( hi ).
"22
DATA(len_str) = strlen( CONV string( conv_xstring ) ).
"11
DATA(len_xstr) = xstrlen( conv_xstring ).
```
#### Character String and Byte String Processing with ABAP Statements
- Several ABAP statements include the `IN CHARACTER MODE` and `IN BYTE MODE` additions.
- These additions determine whether operations process character strings or byte strings.
- If neither option is specified, the default is character string processing (i.e. `IN CHARACTER MODE`).
- Byte string processing with the `IN BYTE MODE` addition is supported by the following ABAP statements: `CONCATENATE`, `FIND`, `REPLACE`, `SHIFT`, `SPLIT`.
- In byte string processing, the data objects used must be byte-like. For character string processing, only character-like data objects are allowed.
The following code snippet explores various statements with the `IN CHARACTER MODE` and `IN BYTE MODE` additions.
```abap
DATA off TYPE i.
DATA(abc_str) = `abc def ghi jkl mno pqr stu vwx yz`.
DATA(copy_str) = abc_str.
*&---------------------------------------------------------------------*
*& FIND and REPLACE statements
*&---------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*& IN CHARACTER MODE addition
*&---------------------------------------------------------------------*
"Searching for the first blank in the string
"3
FIND ` ` IN abc_str IN CHARACTER MODE MATCH OFFSET off.
"The following example is the same as the previous as the IN CHARACTER MODE
"addition is optional. The FIRST OCCURRENCE OF addition is also optional.
"Just using FIND without FIRST OCCURRENCE OF means searching for the first
"occurrence by default.
"3
FIND FIRST OCCURRENCE OF ` ` IN abc_str MATCH OFFSET off.
"Searching for all blanks in the string
FIND ALL OCCURRENCES OF ` ` IN abc_str IN CHARACTER MODE RESULTS DATA(res).
DATA(offsets_of_findings) = concat_lines_of(
table = VALUE string_table( FOR wa IN res ( condense( val = CONV string( wa-offset ) to = `` ) ) ) sep = `, ` ).
"3, 7, 11, 15, 19, 23, 27, 31
"Replacing the first blank in the string
"abc#def ghi jkl mno pqr stu vwx yz
REPLACE ` ` IN abc_str WITH `#` IN CHARACTER MODE.
abc_str = copy_str.
"Replacing all blanks in the string
"abc#def#ghi#jkl#mno#pqr#stu#vwx#yz
REPLACE ALL OCCURRENCES OF ` ` IN abc_str WITH `#` IN CHARACTER MODE.
abc_str = copy_str.
*&---------------------------------------------------------------------*
*& IN BYTE MODE addition
*&---------------------------------------------------------------------*
"Converting to xstring
"6162632064656620676869206A6B6C206D6E6F20707172207374752076777820797A
DATA(abc_xstr) = cl_abap_conv_codepage=>create_out( )->convert( abc_str ).
"20
DATA(blank_xstr) = cl_abap_conv_codepage=>create_out( )->convert( ` ` ).
"23
DATA(repl_xstr) = cl_abap_conv_codepage=>create_out( )->convert( `#` ).
DATA(copy_xstr) = abc_xstr.
"Searching for the first byte that represents a blank in the UTF-8 code page
"3
FIND blank_xstr IN abc_xstr IN BYTE MODE MATCH OFFSET off.
FIND ALL OCCURRENCES OF blank_xstr IN abc_xstr IN BYTE MODE RESULTS res.
"3, 7, 11, 15, 19, 23, 27, 31
DATA(offsets_of_findings_xstr) = concat_lines_of(
table = VALUE string_table( FOR wa IN res ( condense( val = CONV string( wa-offset ) to = `` ) ) ) sep = `, ` ).
"Replacing the first byte that represents a blank in the UTF-8 code page
"6162632364656620676869206A6B6C206D6E6F20707172207374752076777820797A
REPLACE blank_xstr IN abc_xstr WITH repl_xstr IN BYTE MODE.
abc_xstr = copy_xstr.
"Replacing all bytes that represent a blank in the UTF-8 code page
"6162632364656623676869236A6B6C236D6E6F23707172237374752376777823797A
REPLACE ALL OCCURRENCES OF blank_xstr IN abc_xstr WITH repl_xstr IN BYTE MODE.
*&---------------------------------------------------------------------*
*& CONCATENATE statements
*&---------------------------------------------------------------------*
DATA(part_str1) = `abc`.
DATA(part_str2) = `def`.
"abcdef
CONCATENATE part_str1 part_str2 INTO DATA(concat_str) IN CHARACTER MODE.
"abc/def
CONCATENATE part_str1 part_str2 INTO concat_str SEPARATED BY `/` IN CHARACTER MODE.
"Same as above
CONCATENATE part_str1 part_str2 INTO concat_str.
CONCATENATE part_str1 part_str2 INTO concat_str SEPARATED BY `/`.
DATA(part_xstr1) = cl_abap_conv_codepage=>create_out( )->convert( part_str1 ).
DATA(part_xstr2) = cl_abap_conv_codepage=>create_out( )->convert( part_str2 ).
DATA(sep_xstr) = cl_abap_conv_codepage=>create_out( )->convert( `/` ).
"616263646566
CONCATENATE part_xstr1 part_xstr2 INTO DATA(concat_xstr) IN BYTE MODE.
"abcdef
DATA(concat_xstr_converted) = cl_abap_conv_codepage=>create_in( )->convert( concat_xstr ).
"6162632F646566
CONCATENATE part_xstr1 part_xstr2 INTO concat_xstr SEPARATED BY sep_xstr IN BYTE MODE.
"abc/def
concat_xstr_converted = cl_abap_conv_codepage=>create_in( )->convert( concat_xstr ).
"Creating a table of type xstring
DATA(xstr_table) = VALUE xstring_table( ( part_xstr1 ) ( part_xstr2 ) ).
"616263646566
CONCATENATE LINES OF xstr_table INTO DATA(concat_xstr_tab) IN BYTE MODE.
"abcdef
DATA(concat_xstr_tab_converted) = cl_abap_conv_codepage=>create_in( )->convert( concat_xstr_tab ).
*&---------------------------------------------------------------------*
*& SHIFT statements
*&---------------------------------------------------------------------*
DATA(str) = `abcdef`.
DATA(copy) = str.
"bcdef
SHIFT str IN CHARACTER MODE.
str = copy.
"Same as
SHIFT str.
str = copy.
"616263646566
DATA(xstr) = cl_abap_conv_codepage=>create_out( )->convert( str ).
"6263646566
SHIFT xstr IN BYTE MODE.
*&---------------------------------------------------------------------*
*& SPLIT statements
*&---------------------------------------------------------------------*
str = `abc def`.
"`abc` / `def`
SPLIT str AT space INTO DATA(str1) DATA(str2) IN CHARACTER MODE.
SPLIT str AT space INTO TABLE DATA(tab_str) IN CHARACTER MODE.
"Same as above
SPLIT str AT space INTO str1 str2.
SPLIT str AT space INTO TABLE tab_str.
"61626320646566
xstr = cl_abap_conv_codepage=>create_out( )->convert( str ).
"20
blank_xstr = cl_abap_conv_codepage=>create_out( )->convert( ` ` ).
"`616263` / `646566`
SPLIT xstr AT blank_xstr INTO DATA(xstr1) DATA(xstr2) IN BYTE MODE.
SPLIT xstr AT blank_xstr INTO TABLE DATA(xstr_tab) IN BYTE MODE.
```
#### SET BIT and GET BIT Statements
- Unlike the ABAP statements in the previous section, the following statements are are only for byte string processing:
- [`SET BIT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/ABAPSET_BIT.html)
- Syntax pattern: `SET BIT pos OF byte_string [TO value].`
- In a byte-like data object, the bit is set to 1 by default at a specified position, or to 0 or 1 as specified after `TO`.
- Alternatively, you can use the built-in function [`bit-set`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/ABENBIT_FUNCTIONS.html).
- [`GET BIT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/ABAPGET_BIT.html)
- Syntax pattern: `GET BIT pos OF byte_string INTO value.`
- Reads a bit at a specified position in a byte string into a target data object.
Expand the following collapsible section for example code, which experiments with byte string processing (converting a hexadecimal value to the character-like representation of the binary values by reading bits, getting hexadecimal values from the character-like representation of the binary values, setting bits). To try it out, create a demo class named `zcl_demo_abap` and paste the code into it. After activation, choose *F9* in ADT to execute the class. The example is set up to display output in the console.