JSON 数据使用正则表达式反序列化



如果 JSON 包含 \ &",我在使用正则表达式从数据中获取键和值时遇到问题。

{
"KeyOne":"Value One",
"KeyTwo": "Value \ two",
"KeyThree": "Value " Three",
"KeyFour": "ValueFour\"
} 

这是示例数据,我想从中读取值是键。如何使用正则表达式实现。

注意:我正在服务器端(SAP ABAP(反序列化此JSON数据。

在低于 7.2(从内存(的早期版本中,您可以使用类/ui2/cl_json

如果在 7.3 或更高版本上使用支持 JSON 的内核 IXML 编写器。 它比/ui2/cl_json 快几个数量级

您可以在源结构已知的情况下使用身份转换方法 您可以在 ABAP 中创建该结构,或者已经定义了 ABAP 等效项。否则,只需遍历 JSON 文档。 示例字符串很容易解析

编辑:添加示例代码

REPORT zjsondemo.
CLASS lcl DEFINITION CREATE PUBLIC.
PUBLIC SECTION.
METHODS json_stru_known.
METHODS json_stru_traverse.
ENDCLASS.
CLASS lcl IMPLEMENTATION.
METHOD json_stru_known.
DATA l_src_json TYPE string.
DATA l_mara TYPE mara.
WRITE: / 'DEMO 1 Known structure Identity transformation '.
l_src_json = `{"MARA":{"MATNR":"012345678", "MATKL": "DUMMY" }}`.
WRITE: / 'Conver to MARA -> ', l_src_json.
CALL TRANSFORMATION id SOURCE XML l_src_json
RESULT mara = l_mara.  "
WRITE: / 'MARA -  MATNR', l_mara-matnr,
/ '        MATKL', l_mara-matkl.
TYPES:
BEGIN OF lty_foo_bar,
KeyOne TYPE string,
KeyTwo Type string,
KeyThree TYPE string,
KeyFour Type string,
END OF lty_foo_bar.
DATA:
lv_json_string TYPE string,
ls_data TYPE lty_foo_bar.
" in this example we use upper case attribute names 
"because we map to SAP target 
" structure which has upper case names.   
" if you need lowercase variables then you can not map straight to an
" SAP type.  Then you need to use the traverse technique. See example 2
lv_json_string = |{| &&
|"KEYONE":"Value One",| &&
|"KEYTWO": "Value \\ two", | &&
|"KEYTHREE": "Value \" Three", | &&
|"KEYFOUR": "ValueFour\\" | &&
|}|.
lv_json_string = `{"JUNK":` && lv_json_string && `}`.

CALL TRANSFORMATION id SOURCE XML lv_json_string
RESULT junk = ls_data.  "

Write: / ls_data-keyone,ls_data-keytwo, ls_data-keythree , ls_data-keyfour.


ENDMETHOD.
METHOD json_stru_traverse.
DATA l_src_json TYPE string.
DATA: lo_node TYPE REF TO if_sxml_node.
DATA: lif_element       TYPE REF TO if_sxml_open_element,
lif_element_close TYPE REF TO if_sxml_close_element,
lif_value_node    TYPE REF TO if_sxml_value,
l_val             TYPE string,
l_attr            TYPE if_sxml_attribute=>attributes,
l_att_val         TYPE string.
FIELD-SYMBOLS: <attr> LIKE LINE OF l_attr.

WRITE: / 'DEMO 2 Traverse any json  document'.
l_src_json = `{"MATNR":"012345678", "MATKL": "DUMMY", "SOMENODE": "With this value" }`.
WRITE: / 'Parse as JSON with 3 nodes -> ', l_src_json.

DATA(reader) = cl_sxml_string_reader=>create( cl_abap_codepage=>convert_to(  l_src_json ) ).

lo_node = reader->read_next_node( ).   " {
IF lo_node IS INITIAL.
EXIT.
ENDIF.
DO 3 TIMES.

lif_element ?= reader->read_next_node( ).
l_attr =  lif_element->get_attributes( ).
LOOP AT l_attr ASSIGNING <attr>.
l_att_val =  <attr>->get_value( ).
WRITE: / 'Attribute:', l_att_val.
ENDLOOP.
lif_value_node ?= reader->read_next_node( ).
l_val = lif_value_node->get_value( ).
WRITE: '=>',  l_val.
lif_element_close ?= reader->read_next_node( ).

ENDDO.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
DATA lo_lcl TYPE REF TO lcl.
CREATE OBJECT lo_lcl.
lo_lcl->json_stru_known( ).
lo_lcl->json_stru_traverse( ).

SAP系统提供了许多示例程序。 搜索demo*json

SAP docu on json parseing

正如@mrzasa和@joanis在他们的评论中所说:不要使用正则表达式来解析 JSON!

对于小型对象或不需要性能问题时,可以使用/ui2/cl_json

TYPES:
BEGIN OF lty_foo_bar,
KeyOne TYPE string,
KeyTwo Type string,
KeyThree TYPE string,
KeyFour Type string,
END OF lty_foo_bar.
DATA:
lv_json_string TYPE string,
ls_data TYPE lty_foo_bar.
lv_json_string = |{| &&
|"KeyOne":"Value One",| &&
|"KeyTwo": "Value \\ two", | &&
|"KeyThree": "Value \" Three", | &&
|"KeyFour": "ValueFour\\" | &&
|}|.
/ui2/cl_json=>deserialize(
EXPORTING
json = lv_json_string
CHANGING
data = ls_data ).

ls_data-KeyOne包含'Value One'等等。

对于更大的对象和/或更好的性能,请查看下面的@phil soadys 答案中的lxml。无论如何,正确处理大写和小写字母仍然会让ABAP头疼。

最新更新