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

使用正则表达式反序列化JSON数据,json,regex,abap,Json,Regex,Abap,如果JSON包含\&,则在使用正则表达式从数据中获取键和值时,我会遇到问题 { "KeyOne":"Value One", "KeyTwo": "Value \\ two", "KeyThree": "Value \" Three", "KeyFour": "ValueFour\\" } 这是样本数据,从这个我想读的值是键。如何使用正则表达式实现 注意:我正在服务器端SAP ABAP中反序列化此JSON数据。正如@mrzasa和@joanis在他们的评论中所说:不要使

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

{
   "KeyOne":"Value One",
   "KeyTwo": "Value \\ two",
   "KeyThree": "Value \" Three",
   "KeyFour": "ValueFour\\"
} 
这是样本数据,从这个我想读的值是键。如何使用正则表达式实现


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

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

对于小型对象或性能不是问题时,可以使用/ui2/cl_-json:

ls_data-KeyOne包含“值一”等


对于较大的对象和/或更好的性能,请从下面检查lxml。无论如何,正确处理大写和小写字母仍然会让ABAP头疼。

在内存中小于7.2的早期版本中,您可以使用class/ui2/cl\u json

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

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

编辑:添加示例代码

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


如果要解析JSON,请使用JSON解析器,而不是正则表达式。Regexps不是做这件事的合适工具。我不是在UI中做这件事,而是在服务器端做这件事。它在SAP ABAP中。你在ABAP中没有JSON解析器吗?@mrzasa,我修改了我的问题。我需要它在ABAP里。所以,我只能使用正则表达式。我很确定你可以找到ABAP的JSON解析器:尝试用正则表达式解析JSON总是一个坏主意。你介意为OPs问题添加一个最小的工作示例吗?您可以从我的答案中复制类型定义和json字符串初始化。对不起,我指的是一个匹配OPs问题的示例。您刚才添加的代码看起来太复杂了。好吧,长话短说:如果JSON只有大写键,那么使用调用转换进行反序列化是一种简单而高效的方法。。。源XML。否则,您确实需要大量样板代码来处理低级别的内容。如果性能不是我主要关心的问题,我会选择性能差但代码可读的选项。否则,建议使用覆盖范围广泛的单元测试。您是否尝试过针对本地类型使用小写的/ui2/cl_json?Hrm。。老实说:no./ui2/cl_json在大型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 ).
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( ).