原文链接:abap-cheat-sheets/07_String_Processing.md at main · SAP-samples/abap-cheat-sheets · GitHub
原文作者:danrega
介绍
ABAP 为处理字符串提供了大量选项。这些选项包括 ABAP 语句(如 FIND)、字符串表达式(连接 concatenations 和字符串模板)和内置字符串函数(如 strlen)。
💡 Note
字符串的数据类型
ABAP 为包含字符串的数据对象提供了以下内置数据类型。它们的区别如下:
类型 | 描述 | 长度 | 值范围 | 初始值 |
---|---|---|---|---|
string | 用于长度可变的字符串。这种类型的数据对象是动态数据对象,即变量的长度可以在 ABAP 程序执行过程中发生变化,因此可以包含不同长度的字符串。字符串类型的数据对象称为文本字符串 text string,简称字符串 string。 | 没有标准长度;长度可变 | 可在 ABAP 语言代码页 UCS-2 中编码的任何 Unicode 字符。最常见的内容是字母数字字符或特殊字符。 | 长度为 0 的空字符串 |
c | 用于固定长度的字符串。这种类型的数据对象是静态数据对象,即变量的长度必须在声明时定义,在 ABAP 程序执行过程中不会改变。因此,它始终包含相同长度的字符串。c 类型的数据对象称为文本字段 text field。 | 该类型的数据对象可包含一个固定长度的字符串(字符数在 1 到 262143 之间);标准长度:1 | 与字符串 string 相同 | 每个位置都是空白 |
除了这些字符串的主要数据类型外,还有其他几种具有特殊含义的固定长度数据类型:
n
用于长度固定的数字字符串- 这种类型的数据对象在技术上与文本字段几乎相同。不过,唯一有效的字符是数字 0 至 9。在以常规方式赋值时,不检查有效性,只检查无损赋值。因此,此类数字文本字段可以包含无效数据,但只能用于不用于算术计算的数字,如邮政编码或文章编号。每个位置的初始值都是 0。
d
和t
表示日期和时间字段- 这些数据类型的预定义长度为 6 和 8。这些类型的数据对象用于以字符表示预定义格式的日期和时间。您可以在日期和时间计算中直接使用它们。不过,这些字段也可能包含无效值。
这些数据类型在本小抄中不再详述。类似字节的数据类型 x
和 xstring
也是如此,它们与 c
和 string
关系密切,但包含原始字节字符串。
文本字符串(长度可变)与文本字段(长度固定)的区别
- 初始值: 文本字符串的初始值是长度为 0 的空字符串。 文本字段的初始值由每个位置上的空格表示。
- 内部表示法:
c
和string
类型的数据对象都是基本数据对象。不过,文本字段根据其长度占用一个内存块,而文本字符串则是所谓的深层数据对象。就内核来看,它们由指向实际字符的引用来管理。这一事实对使用字符串作为结构组件有限制作用,但由于共享深层数据对象的概念,也可以提高赋值的性能。 - 长度: 理论上,一个文本字符串最多可使用 2 GB(一个字符占用 2 个字节)。文本字段的最大长度为 262143 个字符。
- 尾部空白: 对于文本字符串,在所有操作中都保留尾部空白。对于文本字段,是否保留尾部空白取决于操作数位置。在大多数操作数位置,处理文本字段时,即使使用文本字段字面量,也会截去尾部空白。例如,如果将文本字段赋值给文本字符串,生成的目标字符串将永远不会包含尾部空格。请参阅 “压缩字符串 Condensing Strings ”部分。
- 灵活性: 文本字符串比文本字段更灵活,因为你可以轻松缩短或加长字符串,而不必担心字符串的某些部分会在处理过程中被截断。另一方面,在访问字符串的子串时,您必须确保字符串足够长,而对于文本字段,您总是知道它们的长度。
那么,什么时候该使用什么字符类型呢?文本字段在实际指定最大长度或强制长度时非常有用,例如,国家代码最多只能有两个字符,或者表单中的输入字段不能超过一定长度。如果限制字符串无关紧要,文本字符串也是不错的选择。
声明字符类数据对象
-
要处理字符串,需要基于上述类字符类型的类字符数据对象。
-
在 ABAP 程序中生成文本的最简单方法是字符字面量。下面的代码片段显示了一个实现接口
if_oo_adt_classrun
的全局类。 -
文本字符串字面用后引号 ( `...` )括起来,数据类型为
string
。 -
文本字段用单引号(
'...'
)括起来,数据类型为c
。 -
字面量可以(但根据字面量编程指南(标准 ABAP 的 F1 文档),不应该)像操作数位置的常量一样使用。它们只能在声明命名数据对象时用于起始值。
CLASS zcl_some_test_class DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun.
ENDCLASS.
CLASS zcl_some_test_class 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.
- 已命名的类字符数据类型和对象可以像其他类型和对象一样,通过使用
TYPES
、DATA
CONSTANTS
和引用类字符数据类型来声明。 - 此外,还可以使用操作符
DATA
和FINAL
内联声明类字符数据对象。
语法示例:
" 使用内置类型的类型声明
TYPES: c_type TYPE c LENGTH 3, " 明确的长度规格
str_type TYPE string.
" 使用内置、本地和 DDIC 类型声明数据对象
DATA: flag TYPE c LENGTH 1, " 内置类型
str1 TYPE string, " 内置类型
char1 TYPE c_type, " 本地类型
str2 LIKE str1, " 从本地数据对象派生类型
str3 TYPE str_type, " 本地类型
tstmp TYPE timestampl, " DDIC 类型
char3 TYPE zdemo_abap_flsch-carrid. " 使用 DDIC 表组件类型
" 你可能还会遇到类型为 c,长度被定义在括号 () 中的声明
" 这个方式是不太推荐的
" 为了避免与动态编程中使用的括号相混淆
DATA char(4) TYPE c.
" 只有 TYPE c 规范而没有长度表示 LENGTH 1。
DATA char_len_one TYPE c.
" 无类型和长度说明: 默认类型 c 长度 1
DATA char_no_type_len.
赋值
- 在声明类字符数据对象时,可以直接使用
VALUE
附加语法指定初始值,例如DATA chars TYPE c LENGTH 3 VALUE 'abc'.
。 - 您可以使用赋值操作符
=
对数据对象进行赋值。 - 如上所述,您可以使用操作符
DATA
或FINAL
在行内声明类字符数据对象。 - 您可以在多个写入位置使用运算符。
- 与声明语句中的
VALUE
附加不同,内联声明允许你为表达式的结果或其他返回字符串的位置声明变量。 - 在下面的例子中,在赋值操作符左边以
DATA
(或FINAL
)为前的括号中指定的变量,会自动从右边的操作数中推导出数据类型。这有助于精简程序。
语法示例:
" 数据对象声明,包括使用 VALUE 的默认值
" 注意链式语句: DATA 后跟一个冒号,列出数据对象声明、用逗号隔开。
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'.
" 常量; 内容不能在运行时更改
CONSTANTS pi TYPE p LENGTH 8 DECIMALS 14 VALUE '3.14159265358979'.
" 更多数据对象声明
DATA: char1 TYPE c LENGTH 5,
html TYPE string,
str2 LIKE html.
" 赋值
char1 = 'ab123'.
html = `<p>hallo</p>`.
" 在文本字符串字面量中用另一个后引号转义
str1 = `This is a backquote: ``.`.
" 尽可能避免不必要的类型转换;原则上,每个可转换类型都可以指定
str2 = 'abc'. " 分配给字符串类型数据对象的固定长度字符串
DATA str3 TYPE string VALUE 'X'. " type c length 1
DATA str4 TYPE string VALUE -1. " type i
" 内联声明
DATA(char2) = 'abcd'. "Type c length 4
DATA(str5) = `efgh`.
" 您可以使用 FINAL 创建不可变变量。
FINAL(final_string) = `zyx`.
" 由于 char2 的类型为 c 长度为 4(长度也是派生的)、
" 在以下示例赋值中,字符被截断
" 注意:在较新的 ABAP 版本中,下面的语句显示了语法警告,
” 即字面意义的值(此处故意这样指定)不是目标类型的可接受值。
char2 = 'ijklmnopq'. "ijkl
" 将固定长度字符串分配给可变长度字符串后的尾部空白
DATA(char3) = 'ab '.
DATA(str6) = `cdefgh`.
str6 = char3. " 'ab'(由于转换规则,尾部空白不被处理)
str5 = str3 && ` ` && str4 && `!`. "X 1-!
" 注意 str4 的输出,其中包括上面将类型 i 转换为
" string 类型,这表明可能无意中为 string 类型的 str4指定了整数值。