首页 > 其他分享 >SAP ABAP 基础与入门(一、数据类型定义与字符串处理)

SAP ABAP 基础与入门(一、数据类型定义与字符串处理)

时间:2024-08-02 14:29:22浏览次数:14  
标签:匹配 matcher 数据类型 ABAP result tab SAP TYPE match

1.   基础

1.1.  基本数据类型

CNDTIFPXstringXstring

P:默认为8字节,最大允许16字节。最大整数位:16*2 = 32 - 1 = 31 -14(允许最大小数位数) = 17位整数位

类型

最大长度(字符数)

默认长度

说明

C

1~262143个字符

1 字符

普通字符(常用于名称、备注等字段,是最常用的类型)

N

1~262143个字符

1 字符

0到9之间字符组成的数字字符串

D

8 个字符

日期格式必须为 YYYYMMDD

T

6 个字符

格式为 24-hour的 HHMMSS

I

4 bytes

-2.147.483.648 to +2.147.483.647

F

8 bytes

小数位最大可以到17位,即可精确到小数点后17位

P

1 to 16 bytes

8 bytes

两个数字位压缩后才占一个字节,由于0-9的数字只需要4Bit位,所以一个字节实质上允许存储二位数字,这就是P数据类型为压缩数据类型的由来。并借用半个字节来存储小数点位置、正号、负号相关信息

X

1~524,287 bytes

1 byte

十六进制字符 0-9, A-F具体的范围为:00~FF

类型X是十六进制类型,可表示内存字节实际内容,使用两个十六制字符表示一个字节中所存储的内容。但直接打印输出时,输出的还是赋值时字面意义上的值,而不是Unicode解码后的字符

如果未在 DATA 语句中指定参数<length>,则创建长度为 1

注:如果值是字母,则一定要大写

1.1.1.P类型(压缩型)数据

是一种压缩的定点数,其数据对象占据内存字节数和数值范围取定义时指定的整个数据大小和小数点后位数,如果不指定小数位,则将视为I类型。其有效数字位大小可以是从1~31位数字(小数点与正负号占用一个位置,半个字节),小数点后最多允许14个数字。

P类型的数据,可用于精确运算(这里的精确指的是存储中所存储的数据与定义时字面上所看到的大小相同,而不存在精度丢失问题——看到的就是内存中实实在在的大小)。在使用P类型时,要先选择程序属性中的选项 Fixed point arithmetic(即定点算法,一般默认选中),否则系统将P类型看用整型。其效率低于I或F类型。

"16 * 2 = 32表示了整个字面意义上允许的最大字面个数,而14表示的是字面上小数点后面允许的最大小数位,而不是指14个字节,只有这里定义时的16才表示16个字节

DATA: p(16) TYPE p DECIMALS 14 VALUE '12345678901234567.89012345678901'.

"正负符号与小数点固定要占用半个字节,一个字面上位置,并包括在这16个字节里面。
"16 * 2 = 32位包括了小数点与在正负号在内
"在定义时字面上允许最长可以达到32位,除去小数点与符号需占半个字节以后
"有效数字位可允许31位,这31位中包括了整数位与小数位,再除去定义时小
"数位为14位外,整数位最多还可达到17位,所以下面最多只能是17个9
DATA: p1(16) TYPE p DECIMALS 14 VALUE '-99999999999999999'.

 

"P类型是以字符串来表示一个数的,与字符串不一样的是,P类型中的每个数字位只会占用4Bit位,所以两个数字位才会占用一个字节。另外,如果定义时没有指定小数位,表示是整型,但小数点固定要占用半个字节,所以不带小数位与符号的最大与最小整数如下(最多允许31个9,而不是32个)
DATA: p1(16) TYPE p  VALUE '+9999999999999999999999999999999'.
DATA: p2(16) TYPE p  VALUE '-9999999999999999999999999999999'.

 

其实P类型是以字符串形式来表示一个小数,这样才可以作到精确,就像Java中要表示一个精确的小数要使用BigDecimal一样,否则会丢失精度。

DATA: p(9) TYPE p DECIMALS 2 VALUE '-123456789012345.12'.

”在ABAP 中的负数是负号在右边的,想要转换可以通过函数或者代码进行转换,负号前置
WRITE: / p."123456789012345.12-

DATA f1 TYPE f VALUE '2.0',
      f2 TYPE f VALUE '1.1',
      f3 TYPE f.
f3  =  f1 - f2."不能精确计算
"2.0000000000000000E+00 1.1000000000000001E+00 8.9999999999999991E-01
WRITE: / f1   , f2 , f3.

DATA: p1 TYPE p DECIMALS 1 VALUE '2.0',
      p2 TYPE p DECIMALS 1 VALUE '1.1',
      p3 TYPE p DECIMALS 1.
p3  =  p1 - p2."能精确计算
WRITE: / p1   , p2 , p3. "2.0               1.1               0.9

 

Java中精确计算:

    Public static void main(String[] args) {

        System.out.println(2.0 - 1.1);// 0.8999999999999999

        System.out.println(sub(2.0, 0.1));// 1.9

    }

    Public static double sub(double v1, double v2) {

        BigDecimal b1 = new BigDecimal(Double.toString(v1));

        BigDecimal b2 = new BigDecimal(Double.toString(v2));

        return b1.subtract(b2).doubleValue();

    }

1.2.TYPELIKE

透明表(还有其它数据词典中的类型,如结构)即可看作是一种类型,也可看作是对象,所以即可使用TYPE,也可以使用LIKE:数据元素只能用type,引用表、结构、表类型可以用like

TYPES type6 TYPE mara-matnr.
TYPES type7 LIKE mara-matnr.
DATA obj6 TYPE mara-matnr.
DATA obj7 LIKE mara-matnr.

"SFLIGHT为表类型
DATA plane LIKE sflight-planetype.
DATA plane2 TYPE sflight-planetype.
DATA plane3 LIKE sflight.
DATA plane4 TYPE sflight.
"syst为结构类型
DATA sy1 TYPE syst.
DATA sy2 LIKE syst.
DATA sy3 TYPE syst-index.
DATA sy4 LIKE syst-index.

 

注:定义的变量名千万别与词典中的类型相同,否则表面上即可使用TYPE也可使用LIKE,就会出现这两个关键字(TypeLike)都可用的奇怪现像,下面是定义一个变量时与词典中的结构同名的后果(导致)

DATA : BEGIN OF address2,
  street(20) TYPE c,
  city(20) TYPE c,
END OF address2.
DATA obj4 TYPE STANDARD TABLE OF address2."这里使用的实质上是词典中的类型address2
DATA obj5 LIKE STANDARD TABLE OF address2."这里使用是的上面定义的变量address2

上面程序编译通过,按理obj4定义是通过不过的(只能使用LIKE来引用另一定义变量的类型,TYPE是不可以的),但由于address2是数字词典中定义的结构类型,所以obj4使用的是数字词典中的结构类型,而obj5使用的是LIKE,所以使用的是address2变量的类型

1.3.  DESCRIBE

DESCRIBE FIELD dobj 
  [TYPE typ [COMPONENTS com]] 
  [LENGTH ilen IN {BYTE|CHARACTER} MODE]   "固定长度
  [DECIMALS dec]                 "确定小数点位数
  [OUTPUT-LENGTH olen]  "确定输出长度
  [HELP-ID hlp] 
  [EDIT MASK mask].


DESCRIBE TABLE itab [KIND knd] [LINES lin] [OCCURS n].

解释:蓝色字体为关键字,itab自定义内表名,lin自定义变量,用于储存内表行数,n创建期间决定内表所需要的初始化内存大小

KIND knd

标识为T 时代表标准表,为S时代表排序表,为H时代表哈希表。这些值在类型组SYDES中已被定义成常量sydes_kind-standed ,sydes_kind-sorted,sydes_kind-hashed。

1.4.字符串表达式

可以使用&或&&将多个字符模板串链接起来,可以突破255个字符的限制,下面两个是等效的:

|...| &  |...|

|...| && |...|

如果内容只有字面常量文本(没有变量表达式或控制字符\r \n \t),则不需要使用字符模板,可这样(如果包含了这些控制字符时,会原样输出,所以有这些控制字符时,请使用 |...|将字符包起来):

`...` && `...`

但是上面3个与下面3个是不一样的:

`...` &  `...`

'...' &  '...'

'...' && '...'

上面前两个还是会受255个字符长度限制,最后一个虽然不受255限制,但尾部空格会被忽略

字面常量文本(literal text)部分,使用 ||括起来,不能含有控制字符(如 \r \n \t这些控制字符),特殊字符 |{ } \需要使用 \进行转义:

txt = |Characters \|, \{, and \} have to be escaped by \\ in literal text.|.

字符串表达式

str = |{ ( 1 + 1 ) * 2 }|."算术计算表达式
str = |{ |aa| && 'bb' }|."字符串表达式

str = |{ str }|."变量名

str = |{ strlen( str ) }|."内置函数

1.5.  Data elementDomain

数据元素是构成结构、表的基本组件,域又定义了数据元素的技术属性。Data element主要附带Search Help、Parameter ID、以及标签描述,而类型是由Domain域来决定的。Domain主要从技术方面描述了Data element,如Data Type数据类型、Output Length输出长度、Convers. Routine转换规则、以及Value Range取值范围

将技术信息从Data element提取出来为Domain域的好处:技术信息形成的Domain可以共用,而每个表字段的业务含意不一样,会导致其描述标签、搜索帮助不一样,所以牵涉到业务部分的信息直接Data element中进行描述,而与业务无关的技术信息部分则分离出来形成Domain

1.6.  词典预定义类型与ABAP类型映射

当你在ABAP程序中引用了ABAPDictionary,则预置Dictionary类型则会转换为相应的ABAP类型,预置的Dictionary类型转换规则表如下:

 

Dictionarytype

Meaning

Maximumlengthn

ABAPtype

DEC

Calculation/amountfield

1-31, 1-17intables

P((n+1)/2)

INT1

Single-byte integer

3

Internalonly

INT2

Two-byteinteger

5

Internalonly

INT4

Four-byteinteger

10

I

CURR

Currencyfield货币字段

1-17

P((n+1)/2)

CUKY

Currencykey货币代码

5

C(5)

QUAN

Amount金额

1-17

P((n+1)/2)

UNIT

Unit单位

2-3

C(n)

PREC

Accuracy

2

X(2)

FLTP

Floating pointnumber

16

F(8)

NUMC

Numeritext数字字符

1-255

N(n)

CHAR

Character字符

1-255

C(n)

LCHR

Long character

256-max

C(n)

STRING

Stringofvariable length

1-max

STRING.

RAWSTRING

Byte sequence of variable length

1-max

XSTRING

DATS

Date

8

D

ACCP

Accounting period YYYYMM

6

N(6)

TIMS

Time HHMMSS

6

T

RAW

Byte sequence

1-255

X(n)

LRAW

Long byte sequence

256-max

X(n)

CLNT

Client

3

C(3)

LANG

Language

internal 1, external 2

C(1)

这里的“允许最大长度m”表示的是字面上允许的字符位数,而不是指底层所占内存字节数,如

int1的取值为0~255,所以是3位(不包括符号位)

int2的取值为-32768~32767,所以是5位

lLCHR and LRAW类型允许的最大值为INT2 最大值

lRAWSTRING and STRING 具有可变长度,最大值可以指定,但没有上限

lSSTRING 长度是可变的,其最大值必须指定且上限为255。与CHAR类型相比其优势是它与ABAP type string进行映射。

这些预置的Dictionary类型在创建Data elementDomain时可以引用

Unicode系统中,一个字符占两个字节

1.7.字符串处理

SPLIT dobj AT sep INTO { {result1 result2 ...} | {TABLE result_tab} }必须指定足够目标字段。否则,用字段dobj的剩余部分填充最后目标字段并包含分界符;或者使用内表动态接收

SHIFT dobj {[{BY num PLACES}|{UP TO sub_string}][[LEFT|RIGHT][CIRCULAR]]}
           | { {LEFT DELETING LEADING}|{RIGHT DELETING TRAILING} } pattern

对于固定长度字符串类型,shift产生的空位会使用空格或十六进制的0(如果为X类型串时)来填充

向右移动时前面会补空格,固定长度类型字符串与String结果是不一样:String类型右移后不会被截断,只是字串前面补相应数量的空格,但如果是C类型时,则会截断;左移后后面是否被空格要看是否是固定长度类型的字符串还是变长的String类型串,左移后C类型会补空格,String类型串不会(会缩短)

CIRCULAR:将移出的字符串放在左边或者左边

pattern:只要前导或尾部字符在指定的pattern字符集里就会被去掉,直到第一个不在模式pattern的字符止

CONDENSE <c> [NO-GAPS].如果是C类型只去掉前面的空格(因为是定长,即使后面空格去掉了,左对齐时后面会补上空格),如果是String类型,则后面空格也会被去掉;字符串中间的多个连续的空格使用一个空格替换(String类型也是这样);NO-GAPS:字符串中间的所有空格都也都会去除(String类型也是这样);空格去掉后会左对齐[kənˈdens] 

CONCATENATE {dobj1 dobj2 ...}|{LINES OF itab}[kənˈkatɪneɪt]
            INTO result
            [SEPARATED BY sep]
            [RESPECTING BLANKS].

CDNT类型的前导空格会保留,尾部空格都会被去掉,但对String类型所有空格都会保留;对于c, d, n, t类型的字符串有一个RESPECTING BLANKS选项可使用,表示尾部空格也会保留。注:使用 `` 对String类型进行赋值时才会保留尾部空格  字符串连接可以使用 && 来操作,具体请参考这里

strlen(arg)Xstrlen(arg)String类型的尾部空格会计入字符个数中,但C类型的变量尾部空格不会计算入

substring( val = TEXT [off = off] [len = len] )

count( val = TEXT {sub = substring}|{regex = regex} )匹配指定字符串substring或正则式regex出现的子串次数,返回的类型为i整型类型

contains( val = TEXT REGEX = REGEX)是否包含。返回布尔值,注:只能用在if、While等条件表达式中

matches( val = TEXT REGEX = REGEX)regex表达式要与text完全匹配,这与contains是不一样的。返回布尔值,也只能用在if、While等条件表达式中

match( val = TEXT REGEX = REGEX occ = occ)返回的为匹配到的字符串。注:每次只匹配一个。occ:表示需匹配到第几次出现的子串。如果为正,则从头往后开始计算,如果为负,则从尾部向前计算

find( val = TEXT {sub = substring}|{regex = regex}[occ = occ] )查找substring或者匹配regex的子串的位置。如果未找到,则返回 -1,返回的为offset,所以从0开始

FIND ALL OCCURRENCES OF REGEX regex IN  dobj
  [MATCH COUNT  mcnt]   成功匹配的次数
  { {[MATCH OFFSET moff][MATCH LENGTH mlen]}最后一次整体匹配到的串(整体串,最外层分组,而不是指正则式最内最后一个分组)起始位置与长度
  | [RESULTS result_tab|result_wa] } result_tab接收所有匹配结果,result_wa只能接收最后一次匹配结果
  [SUBMATCHES s1 s2 ...].通常与前面的MATCH OFFSET/ LENGTH一起使用。只会接收使用括号进行分组的子组。如果变量s1 s2 ...比分组的数量多,则多余的变量被initial;如果变量s1 s2 ...比分组的数量少,则多余的分组将被忽略;且只存储第一次或最后一次匹配到的结果

replace( val = TEXT  REGEX = REGEX  WITH = NEW)使用new替换指定的子符串,返回String类型

REPLACE ALL OCCURRENCES OF REGEX regex IN  dobj WITH new

1.7.1.   countmatch结合

DATA: text TYPE string VALUE `Cathy's cat with the hat sat on Matt's mat.`,
      regx TYPE string VALUE `\<.at\>`."\< 单词开头,\> 单词结尾
DATA: counts TYPE i,
index TYPE i,
      substr TYPE string.
WRITE / text.
NEW-LINE.
counts = count( val = text regex = regx )."返回匹配次数
DO counts TIMES.
index = find( val   = text regex = regx occ = sy-index )."返回匹配到的的起始位置索引
  substr = match( val  = text regex = regx occ = sy-index )."返回匹配到的串
index = index + 1.
WRITE AT index substr.
ENDDO.

1.7.字符串处理

SPLIT dobj AT sep INTO { {result1 result2 ...} | {TABLE result_tab} }必须指定足够目标字段。否则,用字段dobj的剩余部分填充最后目标字段并包含分界符;或者使用内表动态接收

SHIFT dobj {[{BY num PLACES}|{UP TO sub_string}][[LEFT|RIGHT][CIRCULAR]]}
           | { {LEFT DELETING LEADING}|{RIGHT DELETING TRAILING} } pattern

对于固定长度字符串类型,shift产生的空位会使用空格或十六进制的0(如果为X类型串时)来填充

向右移动时前面会补空格,固定长度类型字符串与String结果是不一样:String类型右移后不会被截断,只是字串前面补相应数量的空格,但如果是C类型时,则会截断;左移后后面是否被空格要看是否是固定长度类型的字符串还是变长的String类型串,左移后C类型会补空格,String类型串不会(会缩短)

CIRCULAR:将移出的字符串放在左边或者左边

pattern:只要前导或尾部字符在指定的pattern字符集里就会被去掉,直到第一个不在模式pattern的字符止

CONDENSE <c> [NO-GAPS].如果是C类型只去掉前面的空格(因为是定长,即使后面空格去掉了,左对齐时后面会补上空格),如果是String类型,则后面空格也会被去掉;字符串中间的多个连续的空格使用一个空格替换(String类型也是这样);NO-GAPS:字符串中间的所有空格都也都会去除(String类型也是这样);空格去掉后会左对齐[kənˈdens] 

CONCATENATE {dobj1 dobj2 ...}|{LINES OF itab}[kənˈkatɪneɪt]
            INTO result
            [SEPARATED BY sep]
            [RESPECTING BLANKS].

CDNT类型的前导空格会保留,尾部空格都会被去掉,但对String类型所有空格都会保留;对于c, d, n, t类型的字符串有一个RESPECTING BLANKS选项可使用,表示尾部空格也会保留。注:使用 `` 对String类型进行赋值时才会保留尾部空格  字符串连接可以使用 && 来操作,具体请参考这里

strlen(arg)Xstrlen(arg)String类型的尾部空格会计入字符个数中,但C类型的变量尾部空格不会计算入

substring( val = TEXT [off = off] [len = len] )

count( val = TEXT {sub = substring}|{regex = regex} )匹配指定字符串substring或正则式regex出现的子串次数,返回的类型为i整型类型

contains( val = TEXT REGEX = REGEX)是否包含。返回布尔值,注:只能用在if、While等条件表达式中

matches( val = TEXT REGEX = REGEX)regex表达式要与text完全匹配,这与contains是不一样的。返回布尔值,也只能用在if、While等条件表达式中

match( val = TEXT REGEX = REGEX occ = occ)返回的为匹配到的字符串。注:每次只匹配一个。occ:表示需匹配到第几次出现的子串。如果为正,则从头往后开始计算,如果为负,则从尾部向前计算

find( val = TEXT {sub = substring}|{regex = regex}[occ = occ] )查找substring或者匹配regex的子串的位置。如果未找到,则返回 -1,返回的为offset,所以从0开始

FIND ALL OCCURRENCES OF REGEX regex IN  dobj
  [MATCH COUNT  mcnt]   成功匹配的次数
  { {[MATCH OFFSET moff][MATCH LENGTH mlen]}最后一次整体匹配到的串(整体串,最外层分组,而不是指正则式最内最后一个分组)起始位置与长度
  | [RESULTS result_tab|result_wa] } result_tab接收所有匹配结果,result_wa只能接收最后一次匹配结果
  [SUBMATCHES s1 s2 ...].通常与前面的MATCH OFFSET/ LENGTH一起使用。只会接收使用括号进行分组的子组。如果变量s1 s2 ...比分组的数量多,则多余的变量被initial;如果变量s1 s2 ...比分组的数量少,则多余的分组将被忽略;且只存储第一次或最后一次匹配到的结果

replace( val = TEXT  REGEX = REGEX  WITH = NEW)使用new替换指定的子符串,返回String类型

REPLACE ALL OCCURRENCES OF REGEX regex IN  dobj WITH new

1.7.1.   countmatch结合

DATA: text TYPE string VALUE `Cathy's cat with the hat sat on Matt's mat.`,
      regx TYPE string VALUE `\<.at\>`."\< 单词开头,\> 单词结尾
DATA: counts TYPE i,
index TYPE i,
      substr TYPE string.
WRITE / text.
NEW-LINE.
counts = count( val = text regex = regx )."返回匹配次数
DO counts TIMES.
index = find( val   = text regex = regx occ = sy-index )."返回匹配到的的起始位置索引
  substr = match( val  = text regex = regx occ = sy-index )."返回匹配到的串
index = index + 1.
WRITE AT index substr.
ENDDO.

1.7.2. FIND …SUBMATCHES 

DATA: moff TYPE i,
       mlen TYPE i,
       s1   TYPE string,
       s2   TYPE string,
       s3   TYPE string,
       s4   TYPE string.
FIND ALL OCCURRENCES OF REGEX `((\w+)\W+\2\W+(\w+)\W+\3)`"\2 \3 表示反向引用前面匹配到的第二与第三个子串
IN `Hey hey, my my, Rock and roll can never die Hey hey, my my`"会匹配二次,但只会返回第二次匹配到的结果,第一次匹配到的子串不会存储到s1、s2、s3中去
IGNORING CASE
MATCH OFFSET moff
 MATCH LENGTH mlen
SUBMATCHES s1 s2 s3 s4."根据从外到内,从左到右的括号顺序依次存储到s1 s2…中,注:只取出使用括号括起来的子串,如想取整体子串则也要括起来,这与Java不同
WRITE: /  s1, / s2,/ s3 ,/ s4,/ moff ,/ mlen."s4会被忽略

1.7.3.   FIND …RESULTS  itab

DATA: result TYPE STANDARD TABLE OF string WITH HEADER LINE .
"与Java不同,只要是括号括起来的都称为子匹配(即使用整体也用括号括起来了),
"不管括号嵌套多少层,统称为子匹配,且匹配到的所有子串都会存储到,
"MATCH_RESULT-SUBMATCHES中,即使最外层的括号匹配到的子串也会存储到SUBMATCHES 
"内表中。括号解析的顺序为:从外到内,从左到右的优先级顺序来解析匹配结构。
"Java中的group(0)存储的是整体匹配串,即使整体未(或使用)使用括号括起来
PERFORM get_match TABLES result
USING '2011092131221032' '(((\d{2})(\d{2}))(\d{2})(\d{2}))'.
LOOP AT result .
WRITE: / result.
ENDLOOP.
FORM get_match  TABLES p_result"返回所有分组匹配(括号括起来的表达式)
USING    p_str
                         p_reg.
DATA: result_tab TYPE match_result_tab WITH HEADER LINE.
DATA: subresult_tab TYPE submatch_result_tab WITH HEADER LINE.
"注意:带表头时 result_tab 后面一定要带上中括号,否则激活时出现奇怪的问题
FIND ALL OCCURRENCES OF REGEX p_reg IN p_str RESULTS result_tab[].
"result_tab中存储了匹配到的子串本身(与Regex整体匹配的串,存储在
"result_tab-offset、result_tab-length中)以及所子分组(括号部分,存储在
"result_tab-submatches中)
LOOP AT result_tab .
"如需取整体匹配到的子串(与Regex整体匹配的串),则使用括号将整体Regex括起来
"来即可,括起来后也会自动存储到result_tab-submatches,而不需要在这里像这样读取
*    p_result = p_str+result_tab-offset(result_tab-length).
*    APPEND p_result.
    subresult_tab[] = result_tab-submatches.
LOOP AT subresult_tab.
      p_result = p_str+subresult_tab-offset(subresult_tab-length).
APPEND p_result.
ENDLOOP.
ENDLOOP.
ENDFORM.

1.7.2. FIND …SUBMATCHES 

DATA: moff TYPE i,
       mlen TYPE i,
       s1   TYPE string,
       s2   TYPE string,
       s3   TYPE string,
       s4   TYPE string.
FIND ALL OCCURRENCES OF REGEX `((\w+)\W+\2\W+(\w+)\W+\3)`"\2 \3 表示反向引用前面匹配到的第二与第三个子串
IN `Hey hey, my my, Rock and roll can never die Hey hey, my my`"会匹配二次,但只会返回第二次匹配到的结果,第一次匹配到的子串不会存储到s1、s2、s3中去
IGNORING CASE
MATCH OFFSET moff
 MATCH LENGTH mlen
SUBMATCHES s1 s2 s3 s4."根据从外到内,从左到右的括号顺序依次存储到s1 s2…中,注:只取出使用括号括起来的子串,如想取整体子串则也要括起来,这与Java不同
WRITE: /  s1, / s2,/ s3 ,/ s4,/ moff ,/ mlen."s4会被忽略

1.7.3.   FIND …RESULTS  itab

DATA: result TYPE STANDARD TABLE OF string WITH HEADER LINE .
"与Java不同,只要是括号括起来的都称为子匹配(即使用整体也用括号括起来了),
"不管括号嵌套多少层,统称为子匹配,且匹配到的所有子串都会存储到,
"MATCH_RESULT-SUBMATCHES中,即使最外层的括号匹配到的子串也会存储到SUBMATCHES 
"内表中。括号解析的顺序为:从外到内,从左到右的优先级顺序来解析匹配结构。
"Java中的group(0)存储的是整体匹配串,即使整体未(或使用)使用括号括起来
PERFORM get_match TABLES result
USING '2011092131221032' '(((\d{2})(\d{2}))(\d{2})(\d{2}))'.
LOOP AT result .
WRITE: / result.
ENDLOOP.
FORM get_match  TABLES p_result"返回所有分组匹配(括号括起来的表达式)
USING    p_str
                         p_reg.
DATA: result_tab TYPE match_result_tab WITH HEADER LINE.
DATA: subresult_tab TYPE submatch_result_tab WITH HEADER LINE.
"注意:带表头时 result_tab 后面一定要带上中括号,否则激活时出现奇怪的问题
FIND ALL OCCURRENCES OF REGEX p_reg IN p_str RESULTS result_tab[].
"result_tab中存储了匹配到的子串本身(与Regex整体匹配的串,存储在
"result_tab-offset、result_tab-length中)以及所子分组(括号部分,存储在
"result_tab-submatches中)
LOOP AT result_tab .
"如需取整体匹配到的子串(与Regex整体匹配的串),则使用括号将整体Regex括起来
"来即可,括起来后也会自动存储到result_tab-submatches,而不需要在这里像这样读取
*    p_result = p_str+result_tab-offset(result_tab-length).
*    APPEND p_result.
    subresult_tab[] = result_tab-submatches.
LOOP AT subresult_tab.
      p_result = p_str+subresult_tab-offset(subresult_tab-length).
APPEND p_result.
ENDLOOP.
ENDLOOP.
ENDFORM.

1.7.4.正则式类

regex = Regular expression   [ˈreɡjulə]

cl_abap_regex与Java中的 java.util.regex.Pattern的类对应

cl_abap_matcher与Java中的 java.util.regex.Matcher的类对应

1.7.4.1.matchesmatch

是否完全匹配(正则式中不必使用 ^ 与 $);matches为静态方法,而match为实例方法,作用都是一样

DATA: matcher TYPE REF TO cl_abap_matcher,
      match TYPE match_result,
      match_line TYPE submatch_result.
"^$可以省略,因为matches方法本身就是完全匹配整个Regex
IF cl_abap_matcher=>matches( pattern = '^(db(ai).*)$' text = 'dbaiabd' ) = 'X'.
  matcher = cl_abap_matcher=>get_object( )."获取最后一次匹配到的 Matcher 实例
  match = matcher->get_match( ). "获取最近一次匹配的结果(注:是整体匹配的结果)
WRITE / matcher->text+match-offset(match-length).
LOOP AT  match-submatches INTO match_line. "提取子分组(括号括起来的部分)
WRITE: /20 match_line-offset, match_line-length,matcher->text+match_line-offset(match_line-length).
ENDLOOP.
ENDIF.

DATA: matcher TYPE REF TO cl_abap_matcher,
      match TYPE match_result,
      match_line TYPE submatch_result.
"^$可以省略,因为matche方法本身就是完全匹配整个Regex
matcher = cl_abap_matcher=>create( pattern = '^(db(ai).*)$' text = 'dbaiabd' ).
IF matcher->match(  ) = 'X'.
  match = matcher->get_match( ). "获取最近一次匹配的结果
WRITE / matcher->text+match-offset(match-length).
LOOP AT  match-submatches INTO match_line. "提取子分组(括号括起来的部分)
WRITE: /20 match_line-offset, match_line-length,matcher->text+match_line-offset(match_line-length).
ENDLOOP.
ENDIF.

1.7.4.2.contains

是否包含(也可在正则式中使用 ^ 与 $ 用于完全匹配检查,或者使用 ^ 检查是否匹配开头,或者使用 $ 匹配结尾)

DATA: matcher TYPE REF TO cl_abap_matcher,
      match TYPE match_result,
match_line TYPE submatch_result.
IF cl_abap_matcher=>contains( pattern = '(db(ai).{2}b)' text = 'dbaiabddbaiabb' ) = 'X'.
  matcher = cl_abap_matcher=>get_object( ). "获取最后一次匹配到的 Matcher 实例
  match = matcher->get_match( ). "获取最近一次匹配的结果
WRITE / matcher->text+match-offset(match-length).
  LOOP AT  match-submatches INTO match_line. "提取子分组(括号括起来的部分)
WRITE: /20 match_line-offset, match_line-length,matcher->text+match_line-offset(match_line-length).
ENDLOOP.
ENDIF.

1.7.4.3.find_all

一次性找出所有匹配的子串,包括子分组(括号括起的部分)

DATA: matcher TYPE REF TO cl_abap_matcher,
       match_line TYPE submatch_result,
      itab TYPE match_result_tab WITH HEADER LINE.
matcher = cl_abap_matcher=>create( pattern = '<[^<>]*(ml)>' text = '<html>hello</html>' )."创建 matcher 实例
"注:子分组存储在itab-submatches字段里
itab[] = matcher->find_all( ).
LOOP AT itab .
WRITE: / matcher->text, itab-offset, itab-length,matcher->text+itab-offset(itab-length).
  LOOP AT  itab-submatches INTO match_line. "提取子分组(括号括起来的部分)
WRITE: /20 match_line-offset, match_line-length,matcher->text+match_line-offset(match_line-length).
ENDLOOP.
ENDLOOP.

1.7.4.4.find_next

逐个找出匹配的子串,包括子分组(括号括起的部分)

DATA: matcher TYPE REF TO cl_abap_matcher,
      match TYPE match_result, match_line TYPE submatch_result,
      itab TYPE match_result_tab WITH HEADER LINE.
matcher = cl_abap_matcher=>create( pattern = '<[^<>]*(ml)>' text = '<html>hello</html>' ).
WHILE matcher->find_next( ) = 'X'.
  match = matcher->get_match( )."获取最近一次匹配的结果
WRITE: / matcher->text, match-offset, match-length,matcher->text+match-offset(match-length).  
  LOOP AT  match-submatches INTO match_line. "提取子分组(括号括起来的部分)
 WRITE: /20 match_line-offset, match_line-length,matcher->text+match_line-offset(match_line-length).
  ENDLOOP.
ENDWHILE.

1.7.4.5.get_lengthget_offsetget_submatch

DATA: matcher TYPE REF TO cl_abap_matcher,
      length TYPE i,offset TYPE i,
      submatch TYPE string.
matcher = cl_abap_matcher=>create( pattern = '(<[^<>]*(ml)>)' text = '<html>hello</html>' ).
WHILE matcher->find_next( ) = 'X'. "循环2次
"为0时,表示取整个Regex匹配到的子串,这与Java一样,但如果整个Regex使用括号括起来后,
"则分组索引为1,这又与Java不一样(Java不管是否使用括号将整个Regex括起来,分组索引号都为0)
  "上面Regex中共有两个子分组,再加上整个Regex为隐含分组,所以一共为3组
DO 3 TIMES.
"在当前匹配到的串(整个Regex相匹配的串)中返回指定子分组的匹配到的字符串长度
    length = matcher->get_length( sy-index - 1 ).
"在当前匹配到的串(整个Regex相匹配的串)中返回指定子分组的匹配到的字符串起始位置
    offset = matcher->get_offset( sy-index - 1 ).
"在当前匹配到的串(整个Regex相匹配的串)中返回指定子分组的匹配到的字符串
    submatch = matcher->get_submatch( sy-index - 1 ).
WRITE:/ length , offset,matcher->text+offset(length),submatch.
ENDDO.
SKIP.
ENDWHILE.

1.7.4.6.replace_all

DATA: matcher TYPE REF TO cl_abap_matcher,
      count TYPE i,
      repstr TYPE string.
matcher = cl_abap_matcher=>create( pattern = '<[^<>]*>' text = '<html>hello</html>' ).
count = matcher->replace_all( ``)."返回替换的次数
repstr = matcher->text. "获取被替换后的新串
WRITE: / count , repstr.

        

标签:匹配,matcher,数据类型,ABAP,result,tab,SAP,TYPE,match
From: https://blog.csdn.net/weixin_44072448/article/details/140845284

相关文章

  • 数据类型之间的优先级
    数据类型之间的优先级在Java中,数据类型确实有优先级和大小的概念。这主要影响运算时的类型提升规则,以及在进行类型转换时的规则。以下是Java基本数据类型的大小和优先级:大小byte:8位,-128到127short:16位,-32,768到32,767int:32位,-2^31到2^31-1long:64位,-2^63到2^63-......
  • 数据类型之间的强制性转换
    数据类型之间的强制性转换在Java中,数据类型之间的转换主要分为两种:自动类型转换(也称为隐式类型转换)和强制类型转换(也称为显式类型转换)。自动类型转换通常发生在更宽泛的数据类型向更狭窄的数据类型转换时,而强制类型转换则需要程序员显式地进行。自动类型转换(隐式类型转换)自动......
  • 数据类型
    数据类型Java是一种静态类型语言,这意味着每个变量在使用前必须声明其数据类型。Java的数据类型分为两大类:基本数据类型和引用数据类型。基本数据类型基本数据类型是Java语言预定义的,用于存储原始数据的类型。Java有8种基本数据类型:整型:byte:8位有符号整数,取值范围......
  • 数据类型的转换
    数据类型的转换1.隐式类型转换(自动类型转换)隐式类型转换发生在两种情况下:赋值时的转换:当将一个值赋给另一个变量时,如果两个变量的数据类型不兼容,但目标类型的范围能够包含源类型的所有值,则编译器会自动将源类型的值转换为目标类型。例如,在Java中,将int类型的值赋给long类型的变......
  • Lab0 C Programming Lab(CMU)(CSAPP深入理解计算机系统)
    该文章是我在别处写的小随笔,现在转过来实验下载地址15-213/14-513/15-513:IntrotoComputerSystems,Spring2022大致要求1.Linux命令行基础2.C语言基础3.数据结构基础(链表基本操作)4.基本英语阅读能力大致操作下载.tar文件,解压后对着README操作即可;简单来说,允许直......
  • 5分钟掌握软件测试必会mysql数据库知识(数据类型和数据约束
    mysql常用数据类型mysql的常用数据类型,主要有四种,需要我们重点掌握。1整型int整型分成两类,一类是有符号的,就是负数,一类是无符号的,就是正整数。很多时候我们需要的就是无符号的。比如年龄。2小数decimal小数的设置需要我们特别去了解一下。例如:decimal(4,2)这是表示......
  • 数据类型
    基本类型(PrimitiveTypes)基本类型是由Java语言直接提供的,它们不是对象,而是直接的数值或字符。基本类型的数据存储在栈内存中,访问速度较快。Java中有8种基本数据类型,分别是:整型(IntegerTypes)byte:1字节,取值范围-128到127。short:2字节,取值范围-32,768到32,767。int:4字节,取值......
  • ## 数据类型的转换
    数据类型的转换在Java中,数据类型的转换主要分为两大类:基本数据类型之间的转换和与其他类型(如String、数组、集合等)之间的转换。一、基本数据类型之间的转换1.自动类型转换(隐式类型转换)自动类型转换发生在容量小的数据类型转换为容量大的数据类型时,这种转换是自动进行的......
  • 数据类型
    目录1.8种基本数据类型2.引用类型强引用(StrongReference)软引用(SoftReference)弱引用(WeakReference)虚引用(PhantomReference)自定义引用类型1.8种基本数据类型2.引用类型强引用(StrongReference)定义:强引用是最常见的引用类型,也是默认的引用类型。当一个对象具有强引用时,垃圾......
  • CSAPP
    深入理解计算机系统0xff杂项InstructionsetArchitecture:ISA,指令集体系架构软件和硬件之间的一层抽象层冯诺依曼计算机,即程序存储型计算机重要思想:程序就是一系列被编码了的字节序列(看上去和数据一模一样)https://www.cnblogs.com/SovietPower/p/14877143.html0x00参......