【译】07 字符串处理

77 阅读10分钟

原文链接:abap-cheat-sheets/07_String_Processing.md at main · SAP-samples/abap-cheat-sheets · GitHub

原文作者:danrega

介绍

ABAP 为处理字符串提供了大量选项。这些选项包括 ABAP 语句(如 FIND)、字符串表达式(连接 concatenations字符串模板)和内置字符串函数(如 strlen)。

💡 Note

  • 与语句相比,表达式和字符串函数有助于使 ABAP 代码更加简洁明了。例如,您可以直接在操作数位置执行字符串操作,从而避免使用临时变量。
  • 在 ABAP 语句中,对字符串的修改操作通常在读写位置执行,这意味着操作的源字段和目标字段是相同的。在使用字符串函数时,源字段作为输入参数传递,修改后的值作为返回值返回,这意味着函数本身并不修改源字段。当然,您可以将函数赋值给源字段,以实现对源字段的修改。
  • 在大多数情况下,字符串函数提供的功能与相应的 ABAP 语句相同,甚至更多。返回字符串的字符串函数的返回值总是字符串类型 string

字符串的数据类型

ABAP 为包含字符串的数据对象提供了以下内置数据类型。它们的区别如下:

类型描述长度值范围初始值
string用于长度可变的字符串。这种类型的数据对象动态数据对象,即变量的长度可以在 ABAP 程序执行过程中发生变化,因此可以包含不同长度的字符串。字符串类型的数据对象称为文本字符串 text string,简称字符串 string没有标准长度;长度可变可在 ABAP 语言代码页 UCS-2 中编码的任何 Unicode 字符。最常见的内容是字母数字字符或特殊字符。长度为 0 的空字符串
c用于固定长度的字符串。这种类型的数据对象是静态数据对象,即变量的长度必须在声明时定义,在 ABAP 程序执行过程中不会改变。因此,它始终包含相同长度的字符串。c 类型的数据对象称为文本字段 text field该类型的数据对象可包含一个固定长度的字符串(字符数在 1 到 262143 之间);标准长度:1与字符串 string 相同每个位置都是空白

除了这些字符串的主要数据类型外,还有其他几种具有特殊含义的固定长度数据类型:

  • n 用于长度固定的数字字符串
    • 这种类型的数据对象在技术上与文本字段几乎相同。不过,唯一有效的字符是数字 0 至 9。在以常规方式赋值时,不检查有效性,只检查无损赋值。因此,此类数字文本字段可以包含无效数据,但只能用于不用于算术计算的数字,如邮政编码或文章编号。每个位置的初始值都是 0。
  • dt 表示日期和时间字段
    • 这些数据类型的预定义长度为 6 和 8。这些类型的数据对象用于以字符表示预定义格式的日期和时间。您可以在日期和时间计算中直接使用它们。不过,这些字段也可能包含无效值。

这些数据类型在本小抄中不再详述。类似字节的数据类型 xxstring 也是如此,它们与 cstring 关系密切,但包含原始字节字符串

文本字符串(长度可变)与文本字段(长度固定)的区别

  • 初始值: 文本字符串的初始值是长度为 0 的空字符串。 文本字段的初始值由每个位置上的空格表示。
  • 内部表示法cstring 类型的数据对象都是基本数据对象。不过,文本字段根据其长度占用一个内存块,而文本字符串则是所谓的深层数据对象。就内核来看,它们由指向实际字符的引用来管理。这一事实对使用字符串作为结构组件有限制作用,但由于共享深层数据对象的概念,也可以提高赋值的性能。
  • 长度: 理论上,一个文本字符串最多可使用 2 GB(一个字符占用 2 个字节)。文本字段的最大长度为 262143 个字符。
  • 尾部空白: 对于文本字符串,在所有操作中都保留尾部空白。对于文本字段,是否保留尾部空白取决于操作数位置。在大多数操作数位置,处理文本字段时,即使使用文本字段字面量,也会截去尾部空白。例如,如果将文本字段赋值给文本字符串,生成的目标字符串将永远不会包含尾部空格。请参阅 “压缩字符串 Condensing Strings ”部分。
  • 灵活性: 文本字符串比文本字段更灵活,因为你可以轻松缩短或加长字符串,而不必担心字符串的某些部分会在处理过程中被截断。另一方面,在访问字符串的子串时,您必须确保字符串足够长,而对于文本字段,您总是知道它们的长度。

那么,什么时候该使用什么字符类型呢?文本字段在实际指定最大长度或强制长度时非常有用,例如,国家代码最多只能有两个字符,或者表单中的输入字段不能超过一定长度。如果限制字符串无关紧要,文本字符串也是不错的选择。

声明字符类数据对象

  • 要处理字符串,需要基于上述类字符类型的类字符数据对象。

  • 在 ABAP 程序中生成文本的最简单方法是字符字面量。下面的代码片段显示了一个实现接口 if_oo_adt_classrun 的全局类。

    • 使用 write 方法,可以在 ADT 控制台中显示输出结果。在示例中,包含了两个没有专用名称的未定义类型字面量未命名数据对象)。
    • 在下面的例子中,字符字面量的数据类型由分隔符定义。
  • 文本字符串字面用后引号 ( `...` )括起来,数据类型为 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.
  • 已命名的类字符数据类型和对象可以像其他类型和对象一样,通过使用 TYPESDATA CONSTANTS 和引用类字符数据类型来声明。
  • 此外,还可以使用操作符 DATAFINAL 内联声明类字符数据对象。

语法示例:

" 使用内置类型的类型声明

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'.
  • 您可以使用赋值操作符 = 对数据对象进行赋值。
  • 如上所述,您可以使用操作符 DATAFINAL 在行内声明类字符数据对象。
  • 您可以在多个写入位置使用运算符。
  • 与声明语句中的 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指定了整数值。

请注意,还有一个字面运算符 & 可以连接文本字符串字面量,但与 &&很大不同