匹配加减乘除/数组赋值/指针 正则表达式

博客展示了C++相关的正则表达式内容,包含如 [ a-zA-Z0-9][\+\-\*/][ a-zA-Z0-9]、\\w+\\]\\s*=、_t\\s*\\*\\s*[a-z|A-Z] 等表达式示例。

[ a-zA-Z0-9][\+\-\*/][ a-zA-Z0-9]

\w+\]\s*= 

_t\s*\*\s*[a-z|A-Z]

<think> 我们正在处理一个关于SAP ABAP编程的问题:用户希望了解如何将计算公式存储在字符串字段中,然后在程序中进行计算并赋值。 根据用户提供的引用内容,我们可以得到一些线索: 引用[1]提到了动态字段赋值指针的使用,这提示我们可能需要使用字段符号(FIELD-SYMBOLS)或数据引用来实现动态访问。 引用[2]是关于掩码模式的,可能与本问题关联不大。 引用[3]介绍了Dynpro和屏幕事件,但用户的问题是关于计算公式的动态执行,与用户界面关系不大。 因此,我们主要参考引用[1]中提到的动态技术。在ABAP中,动态地执行字符串中的计算公式,通常有以下几种方法: 1. 使用ABAP的`ASSIGN`语句和字段符号来动态地访问字段,但这通常用于访问变量,而不是执行计算表达式。 2. 使用函数`EVAL_FORMULA`(注意:这个函数是SAP Basis 7.02以上版本提供的,用于计算字符串中的算术表达式)。 3. 使用类`CL_JAVA_SCRIPT`来执行类似于JavaScript的计算(但这种方法比较重,且需要配置)。 4. 使用`GENERATE SUBROUTINE POOL`动态生成包含计算表达式的子程序,然后调用。这种方法较为复杂,但灵活。 考虑到用户希望将计算公式存储在字符串中,然后进行计算赋值,最直接的方法是使用函数`EVAL_FORMULA`(如果系统版本支持)。如果系统版本较低,可能需要使用动态生成子程序的方法。 下面我们分别介绍这两种方法: 方法一:使用函数`EVAL_FORMULA` 这个函数可以直接计算一个字符串形式的算术表达式,并返回结果。注意:这个函数只能用于简单的算术运算(加减乘除、括号等),不能包含函数调用或ABAP语句。 示例代码: ```abap DATA: lv_formula TYPE string, lv_result TYPE f. lv_formula = '2 * (3 + 4)'. " 计算公式字符串 CALL FUNCTION 'EVAL_FORMULA' EXPORTING formula = lv_formula IMPORTING value = lv_result EXCEPTIONS OTHERS = 1. IF sy-subrc = 0. WRITE: / '计算结果:', lv_result. ELSE. WRITE: / '计算失败'. ENDIF. ``` 方法二:使用动态生成子程序(如果系统不支持`EVAL_FORMULA`) 这种方法通过动态生成一个包含FORM子程序的程序,然后调用这个子程序来执行计算。 示例代码: ```abap DATA: lv_formula TYPE string, lv_result TYPE f. lv_formula = '2 * (3 + 4)'. " 动态生成子程序 DATA: lv_src TYPE string. CONCATENATE 'FORM compute CHANGING cv_result TYPE f.' 'cv_result =' lv_formula '.' 'ENDFORM.' INTO lv_src SEPARATED BY space. DATA: lt_src TYPE TABLE OF string, lv_prog TYPE sy-repid. APPEND lv_src TO lt_src. " 生成临时子程序池 GENERATE SUBROUTINE POOL lt_src NAME lv_prog. IF sy-subrc = 0. " 调用动态生成的子程序 PERFORM compute IN PROGRAM (lv_prog) CHANGING lv_result. WRITE: / '计算结果:', lv_result. ELSE. WRITE: / '生成子程序失败'. ENDIF. ``` 注意:动态生成子程序的方法需要注意表达式的正确性,否则可能导致语法错误。此外,生成的子程序是临时的,只在当前会话有效。 由于第二种方法比较复杂且有安全风险(如果字符串来自不可信的来源,可能注入恶意代码),因此推荐使用第一种方法(如果系统版本支持)。如果系统版本较低,且需要执行复杂的表达式,可以考虑使用其他方法,比如解析表达式并自己实现计算(这需要较大的工作量)。 根据用户的问题,他可能希望将计算公式存储在数据库表的某个字符串字段中,然后在程序中读取并计算。上述两种方法都可以实现。 最后,提醒用户:动态执行代码存在安全风险,请确保字符串来源可信,或者对字符串内容进行严格的校验。 下面根据要求生成相关问题: §§相关问题§§ 1. 在SAP ABAP中,除了`EVAL_FORMULA`,还有哪些函数或类可以用于执行动态计算公式? 2. 使用`GENERATE SUBROUTINE POOL`动态生成子程序时需要注意哪些安全事项? 3. 如果计算公式中需要引用其他字段的值,应该如何实现? </think> 在SAP ABAP中将计算公式存储在字符串字段并进行动态计算赋值,可通过以下方法实现: ### 方法1:使用字段符号(Field Symbols)动态访问 适用于字段名有规律(如月份字段F001~F012)的场景: ```abap DATA: lv_formula TYPE string VALUE 'F001 + F002 * 0.5'. " 公式字符串 FIELD-SYMBOLS: <fs_field> TYPE any. LOOP AT it_data ASSIGNING <ls_data>. DATA(lv_result) = 0. " 动态解析公式中的字段名 SPLIT lv_formula AT '+' INTO TABLE lt_terms. " 简化示例,实际需完整解析 LOOP AT lt_terms INTO lv_term. " 提取字段名(需更严谨的解析逻辑) lv_fieldname = get_field_from_term( lv_term ). " 动态访问字段值 ASSIGN COMPONENT lv_fieldname OF STRUCTURE <ls_data> TO <fs_field>. lv_result = lv_result + <fs_field>. " 根据运算符处理 ENDLOOP. " 结果存入目标字段 <ls_data>-result = lv_result. ENDLOOP. ``` **优点**:直接访问内存结构,性能高 **限制**:需自行实现公式解析逻辑[^1] ### 方法2:使用`EVAL_FORMULA`函数(SAP_BASIS 7.02+) 直接计算字符串算术表达式: ```abap DATA: lv_formula TYPE string VALUE '2 * (3 + SQRT(16))', lv_result TYPE f. CALL FUNCTION 'EVAL_FORMULA' EXPORTING formula = lv_formula IMPORTING value = lv_result EXCEPTIONS error = 1. ``` **注意**: - 支持基本运算和数学函数(`SQRT`, `SIN`, `LOG`等) - 变量需替换为具体值(如`A+B`需先转义为`2+3`) - 需Basis版本支持[^1] ### 方法3:动态生成子程序(复杂场景) ```abap DATA: lv_formula TYPE string VALUE 'lv_a * lv_b', lv_src TYPE string. CONCATENATE 'FORM compute CHANGING cv_result TYPE f.' 'DATA: lv_a TYPE f VALUE 5, lv_b TYPE f VALUE 10.' 'cv_result =' lv_formula '.' 'ENDFORM.' INTO lv_src. " 动态编译并执行 GENERATE SUBROUTINE POOL lt_src NAME DATA(lv_prog). PERFORM compute IN PROGRAM (lv_prog) CHANGING lv_result. ``` **适用场景**:需要完整ABAP语法支持的复杂计算 **风险**:动态代码存在安全风险,需严格校验输入[^1] ### 最佳实践建议 1. **简单计算**:优先使用`EVAL_FORMULA`函数 2. **带字段名的计算**:结合字段符号动态赋值 3. **输入校验**:使用正则表达式检查公式安全性 `CALL FUNCTION 'CHECK_FORMULA'` 4. **性能敏感场景**:避免在循环内动态编译代码 > 示例:财务月度动态计算场景 > ```abap > LOOP AT gt_faglflext ASSIGNING FIELD-SYMBOL(<fs>). > DATA(lv_sum) = 0. > DO 12 TIMES. > ASSIGN COMPONENT |F0{ sy-index WIDTH = 2 ALIGN = RIGHT PAD = '0' }| > OF STRUCTURE <fs> TO FIELD-SYMBOL(<amt>). > lv_sum = lv_sum + <amt>. > ENDDO. > <fs>-year_total = lv_sum. " 动态求和赋值 > ENDLOOP. > ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值