标签归档:ABAP

SAP OLE中常用的一些方法和属性

1.ole中如何保存和退出。
call method of sheetname ‘saveas’ exporting #1 = filepath #2 =1.
call method of applicationname ‘quit’.
2.给sheet重命名。
call method of sheetname ‘name’ = ‘sheetname’.
3.创建application.
call method of XXX ‘excel.application’.
4.设置XXX的显示模式。
set property of XXX ‘visible’ = 1. 前台运行。为0时表示为后台运行。
5.创建workbook.
CALL METHOD OF EXCEL ‘WORKBOOKS’ = WORKBOOK .
call method of workbook ‘ADD’.
6.在一个workbook中添加一个worksheet.
CALL METHOD OF applicationname ‘sheets’ = worksheet.
call method of worksheet ‘Add’ .
7.给单元格赋值。
CaLL METHOD OF EXCEL ‘CELLS’ = CELL
EXPORTING
#1 = 2
#2 = 2.
Set PROPERTY OF CELL ‘value’ = xxxx.
8.指定要被操作的sheet.
CALL METHOD OF applicationname ‘Worksheets’ = SHEET
EXPORTING
#1 = ‘sheet3’. 这里sheet3为要操作的sheet的名字。
call method of sheet ‘Activate ‘.
9.指定操作的单元格的范围。
CALL METHOD OF applicationname ‘Range’ = range
EXPORTING
#1 = ‘B2’
#2 = ‘c2’.
10. 如何操作范围内的单元格。
call method of range ‘select ‘. range也为已经定义好的ole2_object.
Set PROPERTY OF range ‘MergeCells’ = 0 . 合并单元格,0时不合并,1则合并。与前面一起使用
Set PROPERTY OF range ‘HorizontalAlignment’ = 10 .
Set PROPERTY OF range ‘VerticalAlignment’ = -4108 .
11.单元格内部属性的操作.
call method of cell ‘INTERIOR’ = int.
set property of int ‘ColorIndex’ = color. 颜色
set property of int ‘Pattern’ = pattern.
12.单元格内字体的操作.
call method of CELL ‘FONT’ = font.
set property of font ‘BOLD’ = bold.
set property of font ‘SIZE’ = size.
13.边框的操作.
call method of CELL ‘BORDERS’ = BORDERS
EXPORTING
#1 = ‘1’. 1-left 2-right 3-top 4-bottom
set property of borders ‘Linestyle’ = plinestyle .
set property of borders ‘Weight’ = pweight .
free object borders.
在此之前应该指定range.
14.复制与粘贴.
call method of sheet ‘copy’.
call method of sheet ‘paste’.
15.一点注意。
在操作sheet时,默认为上次操作的sheet.如果想更换,参考8。
16.一个问题。有时输入数据如111111111111111111,会显示为1E+17。
解决办法:
CALL METHOD OF h_excel ‘COLUMNS’ = columnObj
EXPORTING
#1 = 6. “the column number
SET PROPERTY OF columnObj ‘ColumnWidth’ = 10.
SET PROPERTY OF columnObj ‘NumberFormat’ = ‘@’.
17.打开一个workbook.
call METHOD OF workbook ‘Open’ EXPORTING #1 = filename+path.
18. 所有的操作方法都可以在sell—-表 oleload 中 查询到。
19. 执行宏。
CALL METHOD OF EXCEL ‘RUN’ EXPORTING #1 = ‘ZMACRO2’.
20.清除range 内容
CALL METHOD OF EXCEL ‘Range’ = RANGE
EXPORTING
#1 = tar_cell
#2 = tar_cell.
call METHOD of RANGE ‘ClearContents’.
21.合并单元格
CALL METHOD OF EXCEL ‘Range’ = RANGE
EXPORTING
#1 = sor_cell
#2 = tar_cell.
SET PROPERTY OF RANGE ‘MergeCells’ = 1.
22.缩小字体填充
SET PROPERTY OF range ‘ShrinkToFit’ = 0 .
note: 为0时取消缩小字体填充,为1时设置缩小字体填充。
note:
1.与ole相关的关键字存储在表oleload中。
2.如果有些ole方法不熟悉,可以利用vba录制宏来寻找相关的关键字。

HR模块的一些概念以及常用的函数

HR模块的一些概念以及常用的函数

一 HR Components
1. PA-Personnel Management (Master data :0000-0999)
Personnel Administration
Time Management
Payroll
Benefits
Recruitment
Business Trip Management
Table :PAnnnn
Structure:Pnnnn
pannnn:pa master data
pbnnnn: pa applicant data
人事管理主数据:人事管理:入职,分配部门,个人基本信息。。。
(针对员工) 工资管理
福利待遇
出差管理
。。。
时间管理(针对项目)
招聘管理 (针对应聘者)
2.PD-Personnel Development & Planning(Master data:1000-1999)
Organisational Management
Training & Event Management
Personnel Development
Shift Planning
Qualifications / Skills Catalogue
Personnel Costs
Table:HRPnnnn
Stucture:PHInnnn
针对组织部门:认识发展以及计划
组织管理
培训及活动管理:计划
人事发展 :对部门等的要求
shift计划 :串休
技术证书等:级别要求
人事花费:培训,活动等
3.Maintain Object(T-code:pp01)
Main Object Type : Organisational Plan Organisation Unit (O)
Position (S)
Job(C)
Task(T)
Person(P)
Other Object Types Work Centers
Cost Centers
Qualifications
4.Logical Database
PNP: Personnel Administration
PNPCE: Enhance for personnel administration
PCH: Personnel Planning
PAP: Recruitment
pnp 很多时候都替换成了pnpce, 但是使用 Get payroll 的时候 要用pnp 。提到Get Payroll 要注意的是时间不在用pn-begda pn- endda 了 而是要用 pybegda pyendda 或者 pn-begps pn-endps ,前者比较多,这两个的区别有在研究中,用的时候可以 debug一下 看看有没有数据 (*^__^*) 嘻嘻…… 。还有个小技巧,在screen中,不知道field的名称 可以F1查询哦~~

PNP—Table: pernr
Get pernr
PNPCE—-Table:pernr
Nodes:peras
Get peras
PCH—- Table:objec
Get objec.
PAP暂时没用过,以后如果用到在补充。。。待续中。。。。

T-code:se36 see the logical database

顺序:tables: pernr.
nodes:peras.
infotypes:0001.
start-of-selection.
select data. “select要写在get之前,因为get相当于loop,写在里面效率低
Get peras.
read or loop .
end-of-selection.
5.Report Category
change screening
Create a report category and assign it to report
二 Reading Infotypes
1. MACRO(T-code:se11->trmac)
常用 rp_provide_from_last Pnnnn space pn-begda pn-endda(取最新一条数据)
次常用 rp_set_data_interval Pnnnn pn-begda pn-endda
rp_read_all_time_ity
rp_get_hire_date
rp-read-<table>
space or subtype
begda <pn-endda
endda >pn-begda.
pnp-sw-found = 1. 取到数据
2.Function
HR_READ_INFOTYPE
HR_READ_SUBTYPE
HR_INFOTYPE_OPERATION updating infotype records.
operation:MOD(change),COPY,DEL,INS (insert),LIS9(delimit)
3.provide * from p0001
* from p0002
between pn-begda and pn-endda
where……
比较常用的是前两个 尤其第一个 第三个很少用到
三 Time Data
1.Importing Time Data into an Internal Table

INFOTYPES : 0001,
2001 MODE N. ” when mode n,infotype 2001 can’t be got into p2001 using get pernr or peras.
DATA : BEGIN OF ITAB OCCURS 0,
BUKRS LIKE P0001-BUKRS, ” company code
WERKS LIKE P0001-WERKS, ” personnel area
AWART LIKE P2001-AWART, ” 出勤/缺勤的类型
ABWTG LIKE P2001-ABWTG, ” 出勤/缺勤的天数
END OF ITAB.

GET PERNR.

RP_PROVIDE_FROM_LAST P0001 SPACE PN-BEGDA PN-ENDDA.
MOVE-CORRESPONDING P0001 TO ITAB.

RP-READ-ALL-TIME-ITY PN-BEGDA PN-ENDDA. “use this macro to get 2001 time data into p2001

LOOP AT P2001.
MOVE-CORRESPONDING P2001 TO ITAB.
ENDLOOP.

2.Processing Repeat Strictures

* Define Work Area.
DATA: BEGIN OF WAGETYPES,
LGA LIKE P0008-LGA01,
BET LIKE P0008-BET01,
ANZ LIKE P0008-ANZ01,
EIN LIKE P0008-EIN01,
OPK LIKE P0008-OPK01,
END OF WAGETYPES.

GET PERNR.
RP_PROVIDE_FROM_LAST P0008 SPACE PN-BEGDA PN-ENDDA.

DO 20 TIMES VARYING WAGETYPES FROM P0008-LGA01
NEXT P0008-LGA02.
IF not WAGETYPES-LGA IS INITIAL.
WRITE: / WAGETYPES-LGA, WAGETYPES-BET.
ENDIF.
ENDDO.

HR有几个表很特别 就目前知道的是 0008 和0041 都是要do ** times
TABLES:pernr,t548t. ” Date Types
INFOTYPES:0001, ” org.assignment
0041. ” data specification
DATA:BEGIN OF dtype, ” useful in p0014 (Date Specifications)
dar LIKE p0041-dar01, ” Date type
dat LIKE p0041-dat01, ” Date for date type
END OF dtype.
GET pernr.
DO 12 TIMES VARYING dtype-dar FROM p0041-dar01
NEXT p0041-dar02.
IF dtype-dar IS INITIAL.
EXIT.
ELSE.
IF dtype-dar IN datetype. “eq 01
CLEAR data_tab_wa.
endif.

四 Cluster Database Table
1. RPCnxyz:
n=1,2 pcl1 or 2.
xy= cluster eg.RX (pcln-relid) : 不同的pcl是不一样的
z=0 international or country indicater ,always 0.
Macros are used to access the data via the buffer.
2. PCL1 DB for HR work areas
PCL2 Accounting results(time, payroll…)
PCL3 Recruitment data
PCL4 Documents
PCL5 Cost planning

compile payroll results
3.Importing / exporting cluster data
TABLES: PCLn.
INCLUDE RPCnxyz. “Cluster definition
xy-KEY-FIELD = <Value>.
RP-IMP-Cn-xy. / RP-EXP-Cn-xy. ” macro
*display
IF SY-SUBRC NE 0.
WRITE: / ‘Export Failed’.
ENDIF.
4. Display last payroll results use function
RGDIR:Stored payroll results
read cluster directory : CU_READ_RGDIR.
process cluster directory : CU_READ_last
read payroll results: PYXX_READ_PAYROLL_RESULTS
Function module CD_EVALUATION_PERIODS enables you to process table RGDIR.
display the wage types from the results table RT

payroll driver RPCALCn0,use hr data (pannnn) and last payroll results (pcl2)

【ABAP正则表达式】正则表达式在ABAP中的应用

正则表达式(Regular Expressions

正则表达式在其他编程语言中的应用非常广泛,网上资料也非常多,而网上在ABAP语言中应用的资料却很少,尽管各语言中正则表达式语法知识都很类似,但仍然有一些区别,本文主要是简单介绍一下其基本语法。总结一下,方便大家查阅。

一、简要认识

正则表达式就是用一个“字符串”来描述一个特征,然后去验证另一个“字符串”是否符合这个特征。比如表达式“ab+” 描述的特征是“一个 ‘a’ 和任意个 ‘b’ ”,那么 ‘ab’, ‘abb’, ‘abbbbbbbbbb’ 都符合这个特征。

正则表达式可以用来:(1)验证字符串是否符合指定特征,比如验证是否是合法的邮件地址。(2)用来查找字符串,从一个长的文本中查找符合指定特征的字符串,比查找固定字符串更加灵活方便。(3)用来替换,比普通的替换更强大。

举例

DATA: matcher TYPE REF TO cl_abap_matcher,
match   
TYPE c LENGTH 1.
matcher = cl_abap_matcher=>create( pattern     = 
‘\w+@\w+(\.\w+)+’
text        = ‘hubin0809@126.com’ ).
match = matcher->match( ).
WRITE match.
输出结果:X

解释:

1>     ‘\w+@\w+(\.\w+)+’中 \w 是表示任意一个字母或数字或下划线,+ 表示前面字符个数为一个或多个,@即为’@’字符

2>     matcher参照类cl_abap_matcher,match有匹配的意思,调用静态方法create创建了匹配的对(暂时这么理解,好吧,我承认我不知道怎么形容),然后调用match方法,返回值中’X’表示匹配,SPACE表示不匹配。

具体含义后面会讲到,本程序主要是验证邮件地址是否合法。

 

二、语法规则

 

pattern模板,text要匹配的字符,match匹配结果,’X’表示匹配,SPACE表示不匹配。

 

1、 普通字符

 

字母、数字、汉字、下划线、以及后面没有特殊定义的标点符号,都是”普通字符”。表达式中的普通字符,在匹配一个字符串的时候,匹配与之相同的一个字符。

Pattern

Text

Match

A

A

X

A

a

A

AB

AB

AB

X

 

2、 转义字符

 

一些不便书写的字符,采用在前面加 “\” 的方法。例如’.’

表达式

可匹配

\\

代表 “\” 本身

\.

匹配小数点(.)本身

\Q…\E

中间的字符作为普通字符

 

Pattern

Text

Match

.\.

f.

X

.\.

f\f

\w\d

\w\d

\\w\\d

\w\d

X

\Q\w\d\E

\w\d

X

 

3、 能够与 ‘多种字符’ 匹配的表达式

 

正则表达式中的一些表示方法,可以匹配 ‘多种字符’ 其中的任意一个字符。比如,表达式 “\d” 可以匹配任意一个数字。虽然可以匹配其中任意字符,但是只能是一个,不是多个。这就好比玩扑克牌时候,大小王可以代替任意一张牌,但是只能代替一张牌。(没玩过?好吧,去玩qq够级吧,ok,信息泄露了,承认我是山东人)

表达式

可匹配

\d

任意一个数字,0~9 中的任意一个

\w

任意一个字母或数字或下划线,也就是 A~Z,a~z,0~9,_ 中任意一个

\s

包括空格、制表符、换页符等空白字符的其中任意一个

.

小数点可以匹配除了换行符(\n)以外的任意一个字符

 

Pattern

Text

Match

\d

9

X

\d

25

\d\d

25

X

\w

A

X

\s

\n

X

4zF

X

 

4、 自定义能够与 ‘多种字符’ 匹配的表达式

 

使用方括号 [ ] 包含一系列字符,能够匹配其中任意一个字符。用 [^ ] 包含一系列字符,则能够匹配其中字符之外的任意一个字符。同样的道理,虽然可以匹配其中任意一个,但是只能是一个,不是多个。

表达式

可匹配

[ab5@]

匹配 “a” 或 “b” 或 “5” 或 “@”

[^abc]

匹配 “a”,”b”,”c” 之外的任意一个字符

[f-k]

匹配 “f”~”k” 之间的任意一个字母

[^A-F0-3]

匹配 “A”~”F”,”0″~”3″ 之外的任意一个字符

 

Pattern

Text

Match

[abc]

a

X

[abc]

abc

[^abc]b

cb

[a-g]b

cb

X

5、 支持的 POSIX 字符集合

 

POSIX 字符集合

可匹配

[:alnum:]

任何一个字母或数字(A – Z, a – z, 0 – 9)

[:alpha:]

任何一个字母(A – Z, a – z)

[:cntrl:]

任何一个控制字符(\x00 – \x1F, \x7F)

[:digit:]

任何一个数字(0 – 9)

[:space:]

任何一个空白字符(\x09 – \x0D, \x20)

[:graph:]

任何一个可显示的 ASCII 字符,不包含空格

[:lower:]

任何一个小写字母(a – z)

[:upper:]

任何一个大写字母(A – Z)

[:punct:]

可显示字符 [:print:] 中除去字母数字 [:alnum:]

[:blank:]

空格或者制表符(\x20, \x09)

    个人感觉意义不大,可能对一些控制字符有用吧,了解。

 

Pattern

Text

Match

[[:alnum:]]

a

X

[:lower:][:digit:]

a9

X

[[:lower:][:digit:]]

a9

[[:lower:][:digit:]]

b

X

 

6、 修饰匹配次数的特殊符号

 

前面讲到的表达式,无论是只能匹配一种字符的表达式,还是可以匹配多种字符其中任意一个的表达式,都只能匹配一次。如果使用表达式再加上修饰匹配次数的特殊符号,那么不用重复书写表达式就可以重复匹配,否则会累死的。

表达式

作用

{n}

表达式重复n次,比如:”\w{2}” 相当于 “\w\w”;”a{5}” 相当于 “aaaaa”

{m,n}

表达式至少重复m次,最多重复n次,比如:”ba{1,3}”可以匹配 “ba”或”baa”或”baaa”

{m,}

表达式至少重复m次,比如:”\w\d{2,}”可以匹配 “a12″,”_456”,”M12344″…

?

匹配表达式0次或者1次,相当于 {0,1},比如:”a[cd]?”可以匹配 “a”,”ac”,”ad”

+

表达式至少出现1次,相当于 {1,},比如:”a+b”可以匹配 “ab”,”aab”,”aaab”…

*

表达式不出现或出现任意次,相当于 {0,},比如:”*b”可以匹配 “b”,”cccb”…

 

Pattern

Text

Match

[abc]{3}

bca

X

.{3,5}

abcd

X

\d{5,}

12345

X

a*b

b

X

a+b

b

 

7、 其他一些代表抽象意义的特殊符号

 

表达式

作用

^

与字符串开始的地方匹配,不匹配任何字符

$

与字符串结束的地方匹配,不匹配任何字符

\b

匹配一个单词边界,也就是单词和空格之间的位置,不匹配任何字符

|

左右两边表达式之间 “或” 关系,匹配左边或者右边

( )

(1). 在被修饰匹配次数的时候,括号中的表达式可以作为整体被修饰
(2). 取匹配结果的时候,括号中的表达式匹配到的内容可以被单独得到

(?:  )

匹配pattern但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。

 

进一步的文字说明仍然比较抽象,因此,举例帮助大家理解。

举例1:表达式 “^aaa” 在匹配 “xxx aaa xxx” 时,匹配结果是:失败。因为 “^” 要求与字符串开始的地方匹配,因此,只有当 “aaa” 位于字符串的开头的时候,”^aaa” 才能匹配,比如:”aaa xxx xxx”。

举例2:表达式 “aaa$” 在匹配 “xxx aaa xxx” 时,匹配结果是:失败。因为 “$” 要求与字符串结束的地方匹配,因此,只有当 “aaa” 位于字符串的结尾的时候,”aaa$” 才能匹配,比如:”xxx xxx aaa”。

举例3:表达式 “.\b.” 在匹配 “@@@abc” 时,能够找到匹配的内容;匹配到的内容是:”@a”;匹配到的位置是:开始于2,结束于4。
进一步说明:”\b” 与 “^” 和 “$” 类似,本身不匹配任何字符,但是它要求它在匹配结果中所处位置的左右两边,其中一边是 “\w” 范围,另一边是 非”\w” 的范围。

举例4:表达式 “\bend\b” 在匹配 “weekend,endfor,end” 时,能够找到匹配的内容;匹配到的内容是:”end”;匹配到的位置是:开始于15,结束于18。

 

Pattern

Text

Match

(.{1,3})|(.{5,})

bcade

X

 

三、正则表达式中的一些高级规则(ABAP部分支持)

1、 匹配次数中的贪婪与非贪婪

贪婪模式:

 

在使用修饰匹配次数的特殊符号时,有几种表示方法可以使同一个表达式能够匹配不同的次数,比如:”{m,n}”, “{m,}”, “?”, “*”, “+”,具体匹配的次数随被匹配的字符串而定。这种重复匹配不定次数的表达式在匹配过程中,总是尽可能多的匹配。比如,针对文本 “dxxxdxxxd”,举例如下:

表达式 匹配结果
(d)(\w+) “\w+” 将匹配第一个 “d” 之后的所有字符 “xxxdxxxd”
(d)(\w+)(d) “\w+” 将匹配第一个 “d” 和最后一个 “d” 之间的所有字符 “xxxdxxx”。虽然 “\w+” 也能够匹配上最后一个 “d”,但是为了使整个表达式匹配成功,”\w+” 可以 “让出” 它本来能够匹配的最后一个 “d”

由此可见,”\w+” 在匹配的时候,总是尽可能多的匹配符合它规则的字符。虽然第二个举例中,它没有匹配最后一个 “d”,但那也是为了让整个表达式能够匹配成功。同理,带 “*” 和 “{m,n}” 的表达式都是尽可能地多匹配,带 “?” 的表达式在可匹配可不匹配的时候,也是尽可能的 “要匹配”。这种匹配原则就叫作 “贪婪” 模式 。

非贪婪模式:(ABAP暂时不支持,但是最好理解吧)

在修饰匹配次数的特殊符号后再加上一个 “?” 号,则可以使匹配次数不定的表达式尽可能少的匹配,使可匹配可不匹配的表达式,尽可能的 “不匹配”。这种匹配原则叫作 “非贪婪” 模式,也叫作 “勉强” 模式。如果少匹配就会导致整个表达式匹配失败的时候,与贪婪模式类似,非贪婪模式会最小限度的再匹配一些,以使整个表达式匹配成功。举例如下,针对文本 “dxxxdxxxd” 举例:

表达式 匹配结果
(d)(\w+?) “\w+?” 将尽可能少的匹配第一个 “d” 之后的字符,结果是:”\w+?” 只匹配了一个 “x”
(d)(\w+?)(d) 为了让整个表达式匹配成功,”\w+?” 不得不匹配 “xxx” 才可以让后边的 “d” 匹配,从而使整个表达式匹配成功。因此,结果是:”\w+?” 匹配 “xxx”

更多的情况,举例如下:
举例1:表达式 “<td>(.*)</td>” 与字符串 “<td><p>aa</p></td> <td><p>bb</p></td>” 匹配时,匹配的结果是:成功;匹配到的内容是 “<td><p>aa</p></td> <td><p>bb</p></td>” 整个字符串, 表达式中的 “</td>” 将与字符串中最后一个 “</td>” 匹配。
举例2:相比之下,表达式 “<td>(.*?)</td>” 匹配举例1中同样的字符串时,将只得到 “<td><p>aa</p></td>”, 再次匹配下一个时,可以得到第二个 “<td><p>bb</p></td>”。

2、 反向引用 \1, \2

表达式在匹配时,表达式引擎会将小括号 “( )” 包含的表达式所匹配到的字符串记录下来。在获取匹配结果的时候,小括号包含的表达式所匹配到的字符串可以单独获取。这一点,在前面的举例中,已经多次展示了。在实际应用场合中,当用某种边界来查找,而所要获取的内容又不包含边界时,必须使用小括号来指定所要的范围。比如前面的 “<td>(.*?)</td>”。

其实,”小括号包含的表达式所匹配到的字符串” 不仅是在匹配结束后才可以使用,在匹配过程中也可以使用。表达式后边的部分,可以引用前面 “括号内的子匹配已经匹配到的字符串”。引用方法是 “\” 加上一个数字。”\1″ 引用第1对括号内匹配到的字符串,”\2″ 引用第2对括号内匹配到的字符串……以此类推,如果一对括号内包含另一对括号,则外层的括号先排序号。换句话说,哪一对的左括号 “(” 在前,那这一对就先排序号。

举例如下:

举例1:表达式 “(‘|”)(.*?)\1″ 在匹配 ” ‘Hello’, “World” ” 时,匹配结果是:成功;匹配到的内容是:” ‘Hello’ “。再次匹配下一个时,可以匹配到 ” “World” “。

举例2:表达式 “(\w)\1{4,}” 在匹配 “aa bbbb abcdefg ccccc 111121111 999999999” 时,匹配结果是:成功;匹配到的内容是 “ccccc”。再次匹配下一个时,将得到 999999999。这个表达式要求 “\w” 范围的字符至少重复5次,注意与 “\w{5,}” 之间的区别。

举例3:表达式 “<(\w+)\s*(\w+(=(‘|”).*?\4)?\s*)*>.*?</\1>” 在匹配 “<td id=’td1’ style=”bgcolor:white”></td>” 时,匹配结果是成功。如果 “<td>” 与 “</td>” 不配对,则会匹配失败;如果改成其他配对,也可以匹配成功。

3、 预搜索

前面的章节中,我讲到了几个代表抽象意义的特殊符号:”^”,”$”,”\b”。它们都有一个共同点,那就是:它们本身不匹配任何字符,只是对 “字符串的两头” 或者 “字符之间的缝隙” 附加了一个条件。理解到这个概念以后,本节将继续介绍另外一种对 “两头” 或者 “缝隙” 附加条件的,更加灵活的表示方法。

 

正向预搜索:”(?=xxxxx)”,”(?!xxxxx)”
格式:”(?=xxxxx)”,在被匹配的字符串中,它对所处的 “缝隙” 或者 “两头” 附加的条件是:所在缝隙的右侧,必须能够匹配上 xxxxx 这部分的表达式。因为它只是在此作为这个缝隙上附加的条件,所以它并不影响后边的表达式去真正匹配这个缝隙之后的字符。这就类似 “\b”,本身不匹配任何字符。”\b” 只是将所在缝隙之前、之后的字符取来进行了一下判断,不会影响后边的表达式来真正的匹配。
举例1:表达式 “Windows (?=NT|XP)” 在匹配 “Windows 98, Windows NT, Windows 2000” 时,将只匹配 “Windows NT” 中的 “Windows “,其他的 “Windows ” 字样则不被匹配。

举例2:表达式 “(\w)((?=\1\1\1)(\1))+” 在匹配字符串 “aaa ffffff 999999999” 时,将可以匹配6个”f”的前4个,可以匹配9个”9″的前7个。这个表达式可以读解成:重复4次以上的字母数字,则匹配其剩下最后2位之前的部分。当然,这个表达式可以不这样写,在此的目的是作为演示之用。

格式:”(?!xxxxx)”,所在缝隙的右侧,必须不能匹配 xxxxx 这部分表达式。

举例3:表达式 “((?!\bstop\b).)+” 在匹配 “fdjka ljfdl stop fjdsla fdj” 时,将从头一直匹配到 “stop” 之前的位置,如果字符串中没有 “stop”,则匹配整个字符串。

举例4:表达式 “do(?!\w)” 在匹配字符串 “done, do, dog” 时,只能匹配 “do”。在本条举例中,”do” 后边使用 “(?!\w)” 和使用 “\b” 效果是一样的。

表达式

方向

说明

(?=xxx)

正向预搜索(向右)

正向预搜索,判断当前位置右侧是否能匹配指定表达式

(?!xxx)

正向预搜索否定,判断当前位置右侧是否不能够匹配指定表达式

(?<=xxx)

反向预搜索(向左)[ABAP不支持]

反向预搜索,判断当前位置左侧是否能够匹配指定表达式

(?<!xxx)

反向预搜索否定,判断当前位置左侧是否不能够匹配指定表达式

 

4、 其他补充

1>  在表达式 “\s”,”\d”,”\w”,”\b” 表示特殊意义的同时,其大写字母表示相反的意义

表达式 可匹配
\S 匹配所有非空白字符(”\s” 可匹配各个空白字符)
\D 匹配所有的非数字字符
\W 匹配所有的字母、数字、下划线以外的字符
\B 匹配非单词边界,即左右两边都是 “\w” 范围或者左右两边都不是 “\w” 范围时的字符缝隙

2>  在表达式中有特殊意义,需要添加 “\” 才能匹配该字符本身的字符汇总

字符

^

匹配输入字符串的开始位置。要匹配 “^” 字符本身,请使用 “\^”

$

匹配输入字符串的结尾位置。要匹配 “$” 字符本身,请使用 “\$”

( )

标记一个子表达式的开始和结束位置。要匹配小括号,请使用 “\(” 和 “\)”

[ ]

用来自定义能够匹配 ‘多种字符’ 的表达式。要匹配中括号,请使用 “\[” 和 “\]”

{ }

修饰匹配次数的符号。要匹配大括号,请使用 “\{” 和 “\}”

.

匹配除了换行符(\n)以外的任意一个字符。要匹配小数点本身,请使用 “\.”

?

修饰匹配次数为 0 次或 1 次。要匹配 “?” 字符本身,请使用 “\?”

+

修饰匹配次数为至少 1 次。要匹配 “+” 字符本身,请使用 “\+”

*

修饰匹配次数为 0 次或任意次。要匹配 “*” 字符本身,请使用 “\*”

|

左右两边表达式之间 “或” 关系。匹配 “|” 本身,请使用 “\|”

 

四、ABAP中的应用

 

规则终于写完了!其实和其他编程语言规则差不多啦!下面结合ABAP讲讲怎么使用吧,Let’s GO!

不过需要注意, SAP只能是ECC6或者更高版本才可以使用正则(ABAP supports POSIX regular expressions as of Release 7.00)

 

在ABAP中定义了两个类来实现相应功能,分别是

CL_ABAP_REGEX               regex就是regular expression的缩写,里面的方法不是很多,可能用到的也就只有构造方法和REATE_MATCHER这个方法。

CL_ABAP_MATCHER     matcher匹配的意思,也就是说所有的匹配规则都和它有关,里面具体方法,se24去查看

 

其实正则表达式的应用无外乎三种:验证(是否符合规则)、查找(包含提取)、替换

 

1、        验证

实例1

IF CL_ABAP_MATCHER=>MATCHES( PATTERN = ‘\D+’
TEXT    = ‘ZF25’ )
= ABAP_TRUE.
WRITE ‘IS NUMBER’.
ELSE.
WRITE ‘IS NOT NUMBER’.
ENDIF.
输出结果:IS NOT NUMBER

解释:CL_ABAP_MATCHER有一个静态方法,直接进行匹配。

 

2、        查找

实例2

DATA:
MATCHER TYPE REF TO CL_ABAP_MATCHER,
MATCHES TYPE MATCH_RESULT_TAB,
MATCH   LIKE LINE OF MATCHES,
W_TEXT  TYPE STRING.
W_TEXT =  ‘<a id=”MyLinks1_NewPostLink”‘
& ‘ href=”http://www.cnblogs.com/VerySky/admin/EditPosts.aspx?opt=1″>’.
MATCHER = CL_ABAP_MATCHER=>CREATE( PATTERN  = ‘http://.*(?=”)’
TEXT     = W_TEXT ).
MATCHES = MATCHER->FIND_ALL( ).
LOOP AT MATCHES INTO MATCH.
WRITE:/ W_TEXT+MATCH-OFFSET(MATCH-LENGTH).
ENDLOOP.
输出结果:http://www.cnblogs.com/VerySky/admin/EditPosts.aspx?opt=1

解释:

  1. 创建match实例(创建规则),构造方法中有pattern参数输入规则,IGNORE_CASE是否忽略大小写,SIMPLE_REGEX是否使用简单规则(具体参见F1帮助文档),

B.在实例中有FIND_ALL(),FIND_NEXT()方法,可以用来查找。

 

这个方法是不是太麻烦了啊,不急有简单的方法,其实就是字符串处理中用到的。

 

实例3

DATA: patt       TYPE string VALUE n.?w,
text       TYPE string,
result_tab TYPE match_result_tab.
FIELD-SYMBOLS <match> LIKE LINE OF result_tab.
FIND ALL OCCURRENCES OF REGEX patt IN
Everybody knows this is nowhere
RESULTS result_tab.
LOOP AT result_tab ASSIGNING <match>.
WRITE: / <match>-offset, <match>-length.
ENDLOOP.
输出结果:11      324      3

 

实例4

DATA: STR TYPE STRING ,
RESULT_TAB TYPE MATCH_RESULT_TAB ,
WA LIKE LINE OF RESULT_TAB.
*找出STRING里面的双字字符
str = ‘abc我啊adfsf们’.
FIND ALL OCCURRENCES OF REGEX ‘[^\x00-\xff]*’ IN STR RESULTS RESULT_TAB.
LOOP AT RESULT_TAB INTO WA.
WRITE / STR+WA-OFFSET(WA-LENGTH).
ENDLOOP.
输出结果:我啊们

解释:大家都知道英文字母是单字节的,中文是双字节的,但是在ABAP里面用strlen等方法是区别不出单双字节的,这个实例中讲的不失为一个很好的办法。

 

3、        替换

 

实例4

DATA:
MATCHER TYPE REF TO CL_ABAP_MATCHER,
COUNT   TYPE I,
W_TEXT  TYPE STRING,
W_NEWTEXT TYPE STRING.
W_TEXT    = ‘hubinshishuibuzhidao’.
W_NEWTEXT = ‘FFF’.
MATCHER = CL_ABAP_MATCHER=>CREATE( PATTERN  = ‘sh.?i’
TEXT     = W_TEXT ).
WRITE:/ ‘REPLACE BEFORE:’, W_TEXT.
COUNT = MATCHER->REPLACE_ALL( NEWTEXT = W_NEWTEXT ).
WRITE:/ ‘REPLACE COUNT IS:’, COUNT.
WRITE:/ ‘REPLACE AFTER:’, W_TEXT.
输出结果:REPLACE BEFORE: hubinshishuibuzhidaoREPLACE COUNT IS:2

REPLACE AFTER: hubinshishuibuzhidao

大家肯定会说了,字符串前后没有没替换啊。注意修改的不是W_TEXT本身,他将修改后的值放到了MATCHER->TEXT即match类实例的属性里面,我们只需令W_TEXT = MATCHER->TEXT即可。

修改后

DATA:
MATCHER TYPE REF TO CL_ABAP_MATCHER,
COUNT   TYPE I,
W_TEXT  TYPE STRING,
W_NEWTEXT TYPE STRING.
W_TEXT    = ‘hubinshishuibuzhidao’.
W_NEWTEXT = ‘FFF’.
MATCHER = CL_ABAP_MATCHER=>CREATE( PATTERN  = ‘sh.?i’
TEXT     = W_TEXT ).
WRITE:/ ‘REPLACE BEFORE:’, W_TEXT.
COUNT = MATCHER->REPLACE_ALL( NEWTEXT = W_NEWTEXT ).W_TEXT = MATCHER->TEXT.
WRITE:/ ‘REPLACE COUNT IS:’, COUNT.
WRITE:/ ‘REPLACE AFTER:’, W_TEXT.
输出结果:REPLACE BEFORE: hubinshishuibuzhidaoREPLACE COUNT IS:2

REPLACE AFTER: hubinFFFFFFbuzhidao

 

同样这里也有简单方法,字符串处理中的方法也是支持正则的

实例5

DATA TEXT TYPE STRING VALUE ‘-dfufdud-‘.
REPLACE ALL OCCURRENCES OF REGEX ‘u’ IN text WITH ‘x’.
WRITE TEXT.
输出结果:-dfxfdxd-

 

4、        方法语句总结

 

类结

CL_ABAP_MATCHER类里的重要方法

字符串处理中,支持正则的语句

五、补充

 

这里给出ABAP F1帮助中给出的一个特殊字符的列表,很有用的

 

Special Characters in Regular Expressions

The following tables summarize the special characters in regular expressions:

Escape character

Special character Meaning
\ Escape character for special characters

 

Special character for single character strings

Special character Meaning
. Placeholder for any single character
\C Placeholder for any single character
\d Placeholder for any single digit
\D Placeholder for any character other than a digit
\l Placeholder for any lower-case letter
\L Placeholder for any character other than a lower-case letter
\s Placeholder for a blank character
\S Placeholder for any character other than a blank character
\u Placeholder for any upper-case letter
\U Placeholder for any character other than an upper-case letter
\w Placeholder for any alphanumeric character including _
\W Placeholder for any non-alphanumeric character except for _
[ ] Definition of a value set for single characters
[^ ] Negation of a value set for single characters
[ – ] Definition of a range in a value set for single characters
[ [:alnum:] ] Description of all alphanumeric characters in a value set
[ [:alpha:] ] Description of all letters in a value set
[ [:blank:] ] Description for blank characters and horizontal tabulators in a value set
[ [:cntrl:] ] Description of all control characters in a value set
[ [:digit:] ] Description of all digits in a value set
[ [:graph:] ] Description of all graphic special characters in a value set
[ [:lower:] ] Description of all lower-case letters in a value set
[ [:print:] ] Description of all displayable characters in a value set
[ [:punct:] ] Description of all punctuation characters in a value set
[ [:space:] ] Description of all blank characters, tabulators, and carriage feeds in a value set
[ [:unicode:] ] Description of all Unicode characters in a value set with a code larger than 255
[ [:upper:] ] Description of all upper-case letters in a value set
[ [:word:] ] Description of all alphanumeric characters in a value set, including _
[ [:xdigit:] ] Description of all hexadecimal digits in a value set
\a \f \n \r \t \v Diverse platform-specific control characters
[..] Reserved for later enhancements
[==] Reserved for later enhancements

 

Special characters for character string patterns

Special character Meaning
{n} Concatenation of n single characters
{n,m} Concatenation of at least n and a maximum of m single characters
{n,m}? Reserved for later enhancements
? One or no single characters
* Concatenation of any number of single characters including ‘no characters’
*? Reserved for later enhancements
+ Concatenation of any number of single characters excluding ‘no characters’
+? Reserved for later enhancements
| Linking of two alternative expressions
( ) Definition of subgroups with registration
(?: ) Definition of subgroups without registration
\1, \2, \3 Placeholder for the register of subgroups
\Q\E Definition of a string of literal characters
(?) Reserved for later enhancements

 

Special characters for search strings

Special character Meaning
^ Anchor character for the start of a line
\A Anchor character for the start of a character string
$ Anchor character for the end of a line
\Z Anchor character for the end of a character string
\< Start of a word
\> End of a word
\b Start or end of a word
\B Space between characters within a word
(?= ) Preview condition
(?! ) Negated preview condition

 

Special characters for replacement texts

Special character Meaning
$0, $& Placeholder for the whole found location
$1, $2, $3 Placeholder for the register of subgroups
$` Placeholder for the text before the found location
$’ Placeholder for the text after the found location

 

从上面的列表可以看出,ABAP中对“非贪婪模式”(ABAP啊,你不支持啊,你太贪婪了)和“反向预搜索”暂不支持,希望以后能够赶紧扩展功能吧,毕竟很强大的说。

 

正则表达式是需要反复修改,最后才能找到最匹配的规则的,为此ABAP Program里也提供了一个,测试用得小程序,SE38里找DEMO_REGEX_TOY运行即可。

 

在ABAP培训资料里面有一个很有意思的表达式,大家有兴趣可以看一下它能匹配什么文字

^(?=\d)(?:(?:31(?!.(?:0?[2469]|11))|(?:30|29)(?!.0?2)|29(?=.0?2.(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|

(?:(?:16|[2468][048]|[3579][26])00)))(?:\

x20|$))|(?:2[0-8]|1\d|0?[1-9]))([-./])(?:

1[012]|0?[1-9])\1(?:1[6-9]|[2-9]\d)?\d\d(

?:(?=\x20\d)\x20|$))?(((0?[1-9]|1[012])(:

[0-5]\d){0,2}(\x20[AP]M))|([01]\d|2[0-3])

(:[0-5]\d){1,2})?$

 

 

以下附上网上的一些资料:

 

表达式全集

正则表达式有多种不同的风格。下表是在PCRE中元字符及其在正则表达式上下文中的行为的一个完整列表:

字符

描述

\

将下一个字符标记为一个特殊字符、或一个原义字符、或一个向后引用、或一个八进制转义符。例如,“n”匹配字符“n”。“\n”匹配一个换行符。序列“\\”匹配“\”而“\(”则匹配“(”。

^

匹配输入字符串的开始位置。如果设置了RegExp对象的Multiline属性,^也匹配“\n”或“\r”之后的位置。

$

匹配输入字符串的结束位置。如果设置了RegExp对象的Multiline属性,$也匹配“\n”或“\r”之前的位置。

*

匹配前面的子表达式零次或多次。例如,zo*能匹配“z”以及“zoo”。*等价于{0,}。

+

匹配前面的子表达式一次或多次。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等价于{1,}。

?

匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“do”或“does”中的“do”。?等价于{0,1}。

{n}

n是一个非负整数。匹配确定的n次。例如,“o{2}”不能匹配“Bob”中的“o”,但是能匹配“food”中的两个o。

{n,}

n是一个非负整数。至少匹配n次。例如,“o{2,}”不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o。“o{1,}”等价于“o+”。“o{0,}”则等价于“o*”。

{n,m}

mn均为非负整数,其中n<=m。最少匹配n次且最多匹配m次。例如,“o{1,3}”将匹配“fooooood”中的前三个o。“o{0,1}”等价于“o?”。请注意在逗号和两个数之间不能有空格。

?

当该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串“oooo”,“o+?”将匹配单个“o”,而“o+”将匹配所有“o”。

.

匹配除“\n”之外的任何单个字符。要匹配包括“\n”在内的任何字符,请使用像“[.\n]”的模式。

(pattern)

匹配pattern并获取这一匹配。所获取的匹配可以从产生的Matches集合得到,在VBScript中使用SubMatches集合,在JScript中则使用$0…$9属性。要匹配圆括号字符,请使用“\(”或“\)”。

(?:pattern)

匹配pattern但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用或字符“(|)”来组合一个模式的各个部分是很有用。例如“industr(?:y|ies)”就是一个比“industry|industries”更简略的表达式。

(?=pattern)

正向预查,在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配“Windows3.1”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。

(?!pattern)

负向预查,在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如“Windows(?!95|98|NT|2000)”能匹配“Windows3.1”中的“Windows”,但不能匹配“Windows2000”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始

x|y

匹配x或y。例如,“z|food”能匹配“z”或“food”。“(z|f)ood”则匹配“zood”或“food”。

[xyz]

字符集合。匹配所包含的任意一个字符。例如,“[abc]”可以匹配“plain”中的“a”。

[^xyz]

负值字符集合。匹配未包含的任意字符。例如,“[^abc]”可以匹配“plain”中的“p”。

[a-z]

字符范围。匹配指定范围内的任意字符。例如,“[a-z]”可以匹配“a”到“z”范围内的任意小写字母字符。

[^a-z]

负值字符范围。匹配任何不在指定范围内的任意字符。例如,“[^a-z]”可以匹配任何不在“a”到“z”范围内的任意字符。

\b

匹配一个单词边界,也就是指单词和空格间的位置。例如,“er\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”。

\B

匹配非单词边界。“er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er”。

\cx

匹配由x指明的控制字符。例如,\cM匹配一个Control-M或回车符。x的值必须为A-Z或a-z之一。否则,将c视为一个原义的“c”字符。

\d

匹配一个数字字符。等价于[0-9]。

\D

匹配一个非数字字符。等价于[^0-9]。

\f

匹配一个换页符。等价于\x0c和\cL。

\n

匹配一个换行符。等价于\x0a和\cJ。

\r

匹配一个回车符。等价于\x0d和\cM。

\s

匹配任何空白字符,包括空格、制表符、换页符等等。等价于[\f\n\r\t\v]。

\S

匹配任何非空白字符。等价于[^\f\n\r\t\v]。

\t

匹配一个制表符。等价于\x09和\cI。

\v

匹配一个垂直制表符。等价于\x0b和\cK。

\w

匹配包括下划线的任何单词字符。等价于“[A-Za-z0-9_]”。

\W

匹配任何非单词字符。等价于“[^A-Za-z0-9_]”。

\xn

匹配n,其中n为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,“\x41”匹配“A”。“\x041”则等价于“\x04&1”。正则表达式中可以使用ASCII编码。.

\num

匹配num,其中num是一个正整数。对所获取的匹配的引用。例如,“(.)\1”匹配两个连续的相同字符。

\n

标识一个八进制转义值或一个向后引用。如果\n之前至少n个获取的子表达式,则n为向后引用。否则,如果n为八进制数字(0-7),则n为一个八进制转义值。

\nm

标识一个八进制转义值或一个向后引用。如果\nm之前至少有nm个获得子表达式,则nm为向后引用。如果\nm之前至少有n个获取,则n为一个后跟文字m的向后引用。如果前面的条件都不满足,若nm均为八进制数字(0-7),则\nm将匹配八进制转义值nm

\nml

如果n为八进制数字(0-3),且ml均为八进制数字(0-7),则匹配八进制转义值nml。

\un

匹配n,其中n是一个用四个十六进制数字表示的Unicode字符。例如,\u00A9匹配版权符号(?)。

 

常用的正则表达式

正则表达式用于字符串处理、表单验证等场合,实用高效。现将一些常用的表达式收集于此,以备不时之需。

用户名:/^[a-z0-9_-]{3,16}$/

密码:/^[a-z0-9_-]{6,18}$/

十六进制值:/^#?([a-f0-9]{6}|[a-f0-9]{3})$/

电子邮箱:/^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/

URL:/^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/

IP 地址:/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/

HTML 标签:/^<([a-z]+)([^<]+)*(?:>(.*)<\/\1>|\s+\/>)$/

Unicode编码中的汉字范围:/^[u4e00-u9fa5],{0,}$/

匹配中文字符的正则表达式: [\u4e00-\u9fa5]
评注:匹配中文还真是个头疼的事,有了这个表达式就好办了

匹配双字节字符(包括汉字在内):[^\x00-\xff]
评注:可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1)

匹配空白行的正则表达式:\n\s*\r
评注:可以用来删除空白行

匹配HTML标记的正则表达式:<(\S*?)[^>]*>.*?</\1>|<.*? />
评注:网上流传的版本太糟糕,上面这个也仅仅能匹配部分,对于复杂的嵌套标记依旧无能为力

匹配首尾空白字符的正则表达式:^\s*|\s*$
评注:可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式

匹配Email地址的正则表达式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
评注:表单验证时很实用

匹配网址URL的正则表达式:[a-zA-z]+://[^\s]*
评注:网上流传的版本功能很有限,上面这个基本可以满足需求

匹配帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
评注:表单验证时很实用

匹配国内电话号码:\d{3}-\d{8}|\d{4}-\d{7}
评注:匹配形式如 0511-4405222 或 021-87888822

匹配腾讯QQ号:[1-9][0-9]{4,}
评注:腾讯QQ号从10000开始

匹配中国大陆邮政编码:[1-9]\d{5}(?!\d)
评注:中国大陆邮政编码为6位数字

匹配身份证:\d{15}|\d{18}
评注:中国大陆的身份证为15位或18位

匹配ip地址:\d+\.\d+\.\d+\.\d+
评注:提取ip地址时有用

匹配特定数字:
^[1-9]\d*$    //匹配正整数
^-[1-9]\d*$   //匹配负整数
^-?[1-9]\d*$   //匹配整数
^[1-9]\d*|0$  //匹配非负整数(正整数 + 0)
^-[1-9]\d*|0$   //匹配非正整数(负整数 + 0)
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$   //匹配正浮点数
^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$  //匹配负浮点数
^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$  //匹配浮点数
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$   //匹配非负浮点数(正浮点数 + 0)
^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$  //匹配非正浮点数(负浮点数 + 0)
评注:处理大量数据时有用,具体应用时注意修正

匹配特定字符串:
^[A-Za-z]+$  //匹配由26个英文字母组成的字符串
^[A-Z]+$  //匹配由26个英文字母的大写组成的字符串
^[a-z]+$  //匹配由26个英文字母的小写组成的字符串
^[A-Za-z0-9]+$  //匹配由数字和26个英文字母组成的字符串
^\w+$  //匹配由数字、26个英文字母或者下划线组成的字符串

如何写出高效率的正则表达式

如果纯粹是为了挑战自己的正则水平,用来实现一些特效(例如使用正则表达式计算质数、解线性方程),效率不是问题;如果所写的正则表达式只是为了满足一两次、几十次的运行,优化与否区别也不太大。但是,如果所写的正则表达式会百万次、千万次地运行,效率就是很大的问题了。我这里总结了几条提升正则表达式运行效率的经验(工作中学到的,看书学来的,自己的体会),贴在这里。如果您有其它的经验而这里没有提及,欢迎赐教。

为行文方便,先定义两个概念。

误匹配:指正则表达式所匹配的内容范围超出了所需要范围,有些文本明明不符合要求,但是被所写的正则式“击中了”。例如,如果使用\d{11}来匹配11位的手机号,\d{11}不单能匹配正确的手机号,它还会匹配98765432100这样的明显不是手机号的字符串。我们把这样的匹配称之为误匹配。

漏匹配:指正则表达式所匹配的内容所规定的范围太狭窄,有些文本确实是所需要的,但是所写的正则没有将这种情况囊括在内。例如,使用\d{18}来匹配18位的身份证号码,就会漏掉结尾是字母X的情况。

写出一条正则表达式,既可能只出现误匹配(条件写得极宽松,其范围大于目标文本),也可能只出现漏匹配(只描述了目标文本中多种情况种的一种),还可能既有误匹配又有漏匹配。例如,使用\w+\.com来匹配.com结尾的域名,既会误匹配abc_.com这样的字串(合法的域名中不含下划线,\w包含了下划线这种情况),又会漏掉ab-c.com这样的域名(合法域名中可以含中划线,但是\w不匹配中划线)。

精准的正则表达式意味着既无误匹配且无漏匹配。当然,现实中存在这样的情况:只能看到有限数量的文本,根据这些文本写规则,但是这些规则将会用到海量的文本中。这种情况下,尽可能地(如果不是完全地)消除误匹配以及漏匹配,并提升运行效率,就是我们的目标。本文所提出的经验,主要是针对这种情况。

掌握语法细节。正则表达式在各种语言中,其语法大致相同,细节各有千秋。明确所使用语言的正则的语法的细节,是写出正确、高效正则表达式的基础。例如,perl中与\w等效的匹配范围是[a-zA-Z0-9_];perl正则式不支持肯定逆序环视中使用可变的重复(variable repetition inside lookbehind,例如(?<=.*)abc),但是.Net语法是支持这一特性的;又如,JavaScript连逆序环视(Lookbehind,如(?<=ab)c)都不支持,而perl和python是支持的。《精通正则表达式》第3章《正则表达式的特性和流派概览》明确地列出了各大派系正则的异同,这篇文章也简要地列出了几种常用语言、工具中正则的比较。对于具体使用者而言,至少应该详细了解正在使用的那种工作语言里正则的语法细节。

先粗后精,先加后减。使用正则表达式语法对于目标文本进行描述和界定,可以像画素描一样,先大致勾勒出框架,再逐步在局步实现细节。仍举刚才的手机号的例子,先界定\d{11},总不会错;再细化为1[358]\d{9},就向前迈了一大步(至于第二位是不是3、5、8,这里无意深究,只举这样一个例子,说明逐步细化的过程)。这样做的目的是先消除漏匹配(刚开始先尽可能多地匹配,做加法),然后再一点一点地消除误匹配(做减法)。这样有先有后,在考虑时才不易出错,从而向“不误不漏”这个目标迈进。

留有余地。所能看到的文本sample是有限的,而待匹配检验的文本是海量的,暂时不可见的。对于这样的情况,在写正则表达式时要跳出所能见到的文本的圈子,开拓思路,作出“战略性前瞻”。例如,经常收到这样的垃圾短信:“发*票”、“发#漂”。如果要写规则屏蔽这样烦人的垃圾短信,不但要能写出可以匹配当前文本的正则表达式 发[*#](?:票|漂),还要能够想到 发.(?:票|漂|飘)之类可能出现的“变种”。这在具体的领域或许会有针对性的规则,不多言。这样做的目的是消除漏匹配,延长正则表达式的生命周期。

明确。具体说来,就是谨慎用点号这样的元字符,尽可能不用星号和加号这样的任意量词。只要能确定范围的,例如\w,就不要用点号;只要能够预测重复次数的,就不要用任意量词。例如,写析取twitter消息的脚本,假设一条消息的xml正文部分结构是<span class=”msg”>…</span>且正文中无尖括号,那么<span class=”msg”>[^<]{1,480}</span>这种写法的思路要好于<span class=”msg”>.*</span>,原因有二:一是使用[^<],它保证了文本的范围不会超出下一个小于号所在的位置;二是明确长度范围,{1,480},其依据是一条twitter消息大致能的字符长度范围。当然,480这个长度是否正确还可推敲,但是这种思路是值得借鉴的。说得狠一点,“滥用点号、星号和加号是不环保、不负责任的做法”。

不要让稻草压死骆驼。每使用一个普通括号()而不是非捕获型括号(?:…),就会保留一部分内存等着你再次访问。这样的正则表达式、无限次地运行次数,无异于一根根稻草的堆加,终于能将骆驼压死。养成合理使用(?:…)括号的习惯。

宁简勿繁。将一条复杂的正则表达式拆分为两条或多条简单的正则表达式,编程难度会降低,运行效率会提升。例如用来消除行首和行尾空白字符的正则表达式s/^\s+|\s+$//g;,其运行效率理论上要低于s/^\s+//g; s/\s+$//g; 。这个例子出自《精通正则表达式》第五章,书中对它的评论是“它几乎总是最快的,而且显然最容易理解”。既快又容易理解,何乐而不为?工作中我们还有其它的理由要将C==(A|B)这样的正则表达式拆为A和B两条表达式分别执行。例如,虽然A和B这两种情况只要有一种能够击中所需要的文本模式就会成功匹配,但是如果只要有一条子表达式(例如A)会产生误匹配,那么不论其它的子表达式(例如B)效率如何之高,范围如何精准,C的总体精准度也会因A而受到影响。

巧妙定位。有时候,我们需要匹配的the,是作为单词的the(两边有空格),而不是作为单词一部分的t-h-e的有序排列(例如together中的the)。在适当的时候用上^,$,\b等等定位锚点,能有效提升找到成功匹配、淘汰不成功匹配的效率。

SAP ABAP的效率问题与代码优化的小思考

早上老白突然问个无聊的问题:将一个数取反,怎么写速度最快?

进而引发了一群人的探讨:

测试代码:

 

下面代码是测试内表取值速度的:

 

 

最后得出结论:实践出真知,验证之后才知道真正的结果。
流传于ABAP之间的join 不能超过几个表等缪传坑害不少人啊,不能同的情况有不同的优化方案,所以遇到问题时,别急着相信别人的答案,自己先run一下吧。

上面代码出自老白之手,在此声明。

ABAP取汉字的拼音

我们是否遇到过这样的问题?

根据汉字运算出拼音:

那么这个怎么来实现呢?

请参考如下:

 

 
 
代码附件:
取汉字拼音_code

ABAP如何在CALL TRANSFORMATION生成XML时候进行转码

现在遇到一个问题在CALL TRANSFORMATION生成XML时候,默认的是UTF-8(UTF-16)的编码,现在想转成GB2312编码的,那么怎么做到呢?

答案如下:

相关函数

SCMS_STRING_TO_XSTRING

SCMS_BINARY_TO_XSTRING

先将生成的xml 转换成binary 以GB2312(8400)编码,然后再转换回去,最后再替换其中encoding=”UTF-8″位GB2312编码即可。

 

关于ABAP–关于字符串String到XString XString to String转换代码的扩展阅读:

代码如下:

 

相关函数

 

最后感谢老白的支持.

通过宏,指针,Field-symbol实现ABAP动态取得数据

ABAP动态查询的实现:可以完全实现动态查询,每个字段都可以动态。
(1) 利用宏
(2) 利用abap指针
(3) 利用FIELD-SYMBOL

具体实现:
1.结构的动态查询

2.变量的动态查询

3.内表的动态查询

ABAP程序的数据查询语句SELECT的那些事儿

通常使用Open SQL的数据查询语句SELECT将数据库条目选择到内存。
一.SELECT语句:
1)SELECT用于确定读取数据表中的哪些字段;
2)FROM子句用于确定从哪些内表或者视图中读取数据;
3)INTO用于确定将数据读取到程序内的哪些数据对象;
4)WHERE用于限定选择条件;
SELECT select_clause FROM from_clause INTO into_clause WHERE where_clause.
在传统的ABAP语言中,如果使用TABLES语句声明表工作区,则可省略INTO子句(此方法已经被ABAP Object禁用)
除以上4种外还有:
GROUP BY:用于将一组数据条目压缩为一个单行作为选择最终结果;
HAVING:用于限定ORDER BY子句子数据目组的选择条件;
ORDER BY:用于限定行排序;
SELECT整体语法结构:
SELECT <result> FROM <source> INTO <target> [WHERE <condition>] [GROUP BY <fields>] [HAVING <cond>] [ORDER BY <fields>].

二.选择单行数据:
如果只需要选取一个结果数据行,系统在数据库种找到第一个符合条件的数据条目时,就停止查询。单行选择需要在SELECT中使用SINGLE关键字,且INTO自居的结构必须为扁平结构:
SELECT SINGLE <RESULT> INTO <target> FROM <source> …
如果系统找到一个完全符合指定条件的行,SY-SUBRC返回0,否则返回4。
1.选择全部字段
一般不需要指明所有字段,而是在SELECT后用”*”符号,其中INTO语句种的目标对象最好与FROM种的类型相同。
2.选择指定字段
若指定多个数据对象,则需要将这些对象放在括号中,并用逗号隔开,而且其顺序需要与SELECT子句中指明的表字段顺序一致。
如果指定一个扁平结构作为目标对象,且该结构体中的字段多需要选择的字段,则可以使用INTO子句的CORRESPONDING FIELDS选项,该选项只会将SELECT子句中指明字段的内容传送到目标工作区的同名组建中。

三.选择多行数据
将符合条件的数据全部选取出,其语句结构也需要有相应变化,包括循环选择和选择至内表,两种情况。多行选择也可以使用“*”选择整行数据或指定要选择的字段列表。
1.循环选择
通过SELECT / ENDSELECT循环从数据库中读取多行。
SELECT [DISTINCT] <result>…<statement block> ENDSELECT.
注:使用DISTINCT自动去掉重复的行;SY-DBCNT(系统字段)为每次循环计数;对三塔tement block中语句块进行处理。
2.选择至内表
克刚变得一次性把数据选择到一个内表中去。
SELECT …INTO|APPENDING[CORRESPONDING FIELDS OF]TABLE itab.
注:该情况下SELECT并不启动循环,因而不需要使用ENDSELECT语句;如果itab非空,则SELECT语句将用读取的数据覆盖其中的内容,使用APPENDING代替INTO将布覆盖内表,若结构不完全相同,也可使用CORRESPONDING FIELDS选项将同名区域相对应。
3.指定选择包大小
包的大小指的是一次选择到内表的行数,可使用INTO子句的PACKAGE SIZE选项。
SELECT * … INTO TABLE itab PACKAGE SIZE n …
<statement block>
ENDSELECT.
注:由于指定了包的大小,该语句以循环的形式出现;如果n小于等于0,将出现运行是错误。

四.指定查询条件:
1.比较运算符:(=、<、>、<>、<=、>=及相应关键字)
WHERE … f <operator>g … //f为不带前缀数据表名称的字段名FROM中指定,g任意数据对象。
2.范围限定运算符:
WHERE … f[NOT]BETWEEN g1 AND g2 … //条目中f必须在g1与g2之间的值。
3.字符比较运算符:
WHERE f[NOT]LIKE g [ESCAPE h] … //数据条目中,字段f值必须符合g的模式。g中通配符“_”用于代替单个字符,“%”用于代替任意字符串(包含空串)。
注:可使用ESCAPE选项指定一个忽略符号(h),如果通配符前有忽略符号,那么通配符和忽略符号本身都失去了其功能,而是还原为本义。
4.检查列表值:
WHERE … f[NOT] IN (g1,…,gn)… //来价差数据库字段f中的值是否等于括号内列表中的一个值。
e.g. SELECT … WHERE city IN(‘beijing’,’rome’,’london’).
5.检查空值:
WHERE … f IS[NOT] NUll … //来判断数据库字段f中的值是否为空值。
注:在ABAP中,特定的数据对象都具有初始值,这些初始值可能是一串0或空格等,但不等同于数据库中的NULL值,因而使用ABAP语句添加数据条目时,所有的数据字段都不可能是空值。但在ABAP数据词典里仍有可能存在控制字段,因为Native SQL可以进行空值设置。
6.检查选择:
选择表是一种复杂而强大的逻辑表达式组合形式,其本身是一个内表,检查选择表意味着数据库字段f需满足所有逻辑表达式的组合。
WHERE … f [NOT] IN seltab …
其中seltab是选择标准表,是具有特定格式的内表,可以通过SELECT-OPTIONS语句添加到程序和报表选择屏幕,并由报表用户填充它。
查询条件也可在全部或者部分运行时动态指定,方法为在程序中将所有选择条件放置于一个内表中。
SELECT … WHERE <condition> AND (itab) …
内表itab金包含一个类型c组件且最大长度为72的字段。

五.夺标结合查询
应用程序需要从相关联的多个数据库表读取数据进行评估,此时需要用某些结合条件(字段)把各个数据库表连接起来。
1.SELECT语句嵌套:
2.FOR ALL ENTRIES选项:
Open SQL在WHERE子句中提供了FOR ALL ENTRIES附加项,选出符合已存在内表中所有满足条件的数据值:
SELECT … FOR ALL ENTRIES IN itab WHERE <condition> …
3.使用视图:
可通过视图(view)将多个数据库表的选择结合在同一个SELECT居于中进行。
4.结合查询(Join)
Inner Jion基本思想是如果主数据表和结合表中存在共同的字段内容,根据其相同值提取
SELECT … FROM table [INNER] JOIN
jointable1[AS alias]ON<cond><options>,
jointable2[AS alias]ON<cond><options>…
table是主选择表;jointable是结合表;ON用于指定结合条件;
注:不同逻辑条件之间只能通过AND连接,且每个条件中必须包含一个主选择表中的字段,可用“~”指定其所属的数据库表作为前缀。
LeftOuterJoin与InnerJoin的主要区别是前者中对于主选择表的数据,即使在结合数据表中条件字段只不存在,也将该数据行选出,结合表中不存在的字段保持空白。
SELECT … FROM table LEFT[OUTER]JOIN dbtab [AS alias] ON <cond><options>…
ON附加项中,只能使用“=”操作符。
5.子查询
使用EXISTS,IN或者逻辑运算符连接至WHERE子句中,但不能与结合选择附加项ON同时出现,子查询可进行嵌套。

六.组合查询结果
1.总计功能:
特定字段:MAX最大值、MIN最小值、SUM求和、AVG平均值、COUNT行数。
SELECT agg ([DISTINCT] s1)[AS a1] agg ([DISTINCT] s1)[AS a1] …
agg:总计的表达式;s1:字段;a1:目标变量;DISTINCT排出相同的选择结果。
2.分组总计:
使用GROUP BY子句进行分组总计,注:分组总计只能应用在查询字段已经指定了的情况,因此只有指定单独的基本字段列表或者使用INTO CORRESPONDING FIELD附加项的SELECT语句才能进行分组选择。
SELECT s1[AS a1] s2[AS a2] … agg(sm)[AS am] agg(sn)[AS an]…
INTO (f1,f2,…fm,fn)|COORESPONDING FIELD OF itab…
GROUP BY s1,s2 …
3.指定分组条件:
使用HAVING子句给分组选择的结果限定条件。注:只有使用GROUP BY时才可使用。
SELECT s1[AS a1] s2[AS a2] … agg(sm)[AS am] agg(sn)[AS an]…
INTO (f1,f2,…fm,fn)|COORESPONDING FIELD OF itab…
GROUP BY s1,s2 …
HAVING <cond>.
<cond>用法与WHERE子句中规则一致。
4.指定行的顺序:
ORDER BY 子句指定行的顺序,排序标准是数据表住关键字或指定的字段。
SELECT * FROM … ORDER BY PRIMARY KEY. //系统以升序次序给出
SELECT * FROM … ORDER BY f1[ASCENDING|DESCENDING] f2[ASCENDING|DESCENDING] … //默认为升序,先按f1排,后按f2排

七.其它格式说明
1.使用标工作区: TABLES dbtab
标工作区是接口工作区中的一种,使用TABLES语句声明,在ABAP objects中不能再使用该语句格式,在指定了标工作区之后,SELECT语句中可省略INTO子句。
2.动态指定数据库表
SELECT …FROM (dbtabname)…
通过在运行时为变量值指定数据库表名。
注:dbtabname必须包含一个数据库表名字,且必须为大写形式,不能使用表工作区忽略INTO子句。
e.g. dbtabname=’SPFLI’
3.指定数据区域
不同应用被分为若干个商业区域,这些区域称为集团(Client)。每个集团都会被系统自动分配一个默认字段MANDT,
注:一些系统通用表是集团无关的,可跨区域存储无MANDT字段。
若要操作特定集团,则需要使用CLENT SPECIFIED取消系统自动处理功能。
SELECT|UPDATE … dbtab CLENT SPECIFIED …
注:CLENT SPECIFIED紧跟在表名之后,并在WHERE对mandt的集团字段进行使用。
4.设置缓冲机制
在数据字典Technical settings中进行不同类型缓冲设定。
SELECT语句中的FROM子句的BYPASSING BUFFER附加项,可取消数据字典对该表的缓冲。
DISTINCT附加项与结合选择、总计选择、IS NULL条件、子查询,以及GROUP BY和ORDER BY同时使用时,也将自动忽略缓冲设定。
SELECT … FROM dbtab BYPASSING BUFFER …
5.限定选择行数
SELECT … FROM dbtab UP TO n ROWS …
若n为正数,则系统最获选n行到程序中,若n为0,则选所有满足的行。
注:与ORDER BY同时使用时先排序,再从排序结果中选n行。
6.操作性能分析
GET RUN TIME FIELD f.
f为I类型,返回开始后的毫秒数。可得到当前系统已运行的时间,来分析SQL语句的操作性能。
注:若需要对程序进行更为复杂、全面性能分析,可以使用系统工具Runtime Aralysis(SE30)。
八.使用光标
在SELECT语句中,数据从数据库中以32KB的数据包传递至应用服务器中,并通过INTO子句传至ABAP中,Open SQL中提供了一套语句对数据的具体传输过程进行监测,这个监测通过操作数据库光标进行,使用光标几乎可以从任何SELECT语句的结果集中获得下一行,先用OPEN CURSOR语句将光标与相关的SELECT语句连接起来。
OPEN CURSOR [WITH HOLD] c FOR SELECT … [WHERE (conditions)].
其中:c为CURSOR类型,不能在SELECT SINGLE中使用光标。
打开光标后,就可使用FETCH语句从OPEN CURSOR的结果集中读下一行
FETCH NEXT CURSOR c INTO <target>.
其中所选行都将读到INTO子句指定的目标区域。若FETCH没有读取任何行SY-SUBRC为4,否则返回4。
必须使用CLOSE CURSOR c 来关闭光标
数据库提交时,系统将自动关闭光标,若在OPEN CURSOR中使用WITH HOLD选项,则Native SQL数据库提交将不会关闭光标。