ABAP中如何将字面量文本动态转换为可解析的字符串模板
ABAP 的字符串模板 |...| 是编译期语法,只有代码中硬编码在模板内的 {} 占位符会在编译阶段解析为变量/表达式取值,运行期存储在变量中的 {} 字符只会被识别为普通文本,不会触发模板解析逻辑,因此你之前的写法无法得到预期结果。
以下是两种可行的实现方案:
方案1:正则匹配+动态取值(轻量、安全)
适用于占位符为全局可访问变量(如系统变量SY结构、自定义全局变量、数据字典元素)、无需复杂表达式的场景
DATA(literal) = 'Hello { sy-uname }! Today is { sy-datum }'. " 匹配{ xxx }格式的占位符,提取变量名 DATA(lo_regex) = NEW cl_abap_regex( pattern = '\{\s*(\w+(-\w+)?)\s*\}' ). DATA(lo_matcher) = lo_regex->create_matcher( text = literal ). DATA(lv_result) = literal. WHILE lo_matcher->find_next( ) = abap_true. DATA(lv_varname) = lo_matcher->get_submatch( 1 ). " 动态访问变量 ASSIGN (lv_varname) TO FIELD-SYMBOL(<fs_var>). IF sy-subrc = 0. REPLACE FIRST OCCURRENCE OF lo_matcher->get_match( ) IN lv_result WITH <fs_var>. ENDIF. ENDWHILE. cl_demo_output=>display( lv_result ).
方案2:动态生成代码(支持任意表达式)
如果你的模板中需要使用函数调用、运算等复杂表达式,可以通过动态生成子程序池的方式实现完全等效于硬编码字符串模板的解析能力:
DATA(literal) = 'Hello { sy-uname }! Your user ID length is { strlen( sy-uname ) }'. " 拼接动态程序代码 DATA(lt_code) = VALUE string_table( ( `PROGRAM dyn_subpool.` ) ( `FORM parse_template CHANGING cv_result TYPE string.` ) ( ` cv_result = |` && literal && `|.` ) ( `ENDFORM.` ) ). " 生成动态子程序池 GENERATE SUBROUTINE POOL lt_code NAME DATA(lv_pool_name). IF sy-subrc = 0. DATA(lv_result) = ``. PERFORM ('PARSE_TEMPLATE') IN PROGRAM (lv_pool_name) CHANGING lv_result. cl_demo_output=>display( lv_result ). ENDIF.
注意:该方案存在代码注入风险,如果模板字符串
literal的内容来自外部用户输入,必须提前做严格的内容校验,避免执行恶意代码。方案要求ABAP版本为7.40及以上。
内容的提问来源于stack exchange,提问作者biscuit
相关产品推荐
相关产品推荐

