rplantiko

Grouping a string in blocks

Mar 26th, 2020 (edited)
1,512
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
ABAP 3.89 KB | None | 0 0
  1. *&---------------------------------------------------------------------*
  2. *& Report ZZ_DIGIT_GROUPS
  3. *&---------------------------------------------------------------------*
  4. *& Zeichenfolge von rechts in Fünferblöcke gruppieren
  5. *& (wie in ESR-Einzahlungsscheinen die Referenznummern)
  6. *&---------------------------------------------------------------------*
  7. *& Es ist gut, sich in Übungsaufgaben dieser Art zu erproben,
  8. *& nicht weil es eine konkrete Arbeitsaufgabe wäre,
  9. *& sondern um sich an ihr zu fragen:
  10. *&  • Was hat man für Möglichkeiten (Ideen für Algorithmen finden)?
  11. *&  • Wird es besser unter Zuhilfenahme neuerer ABAP-Funktionen?
  12. *&  • Wie lesbar wird der Code?
  13. *&  • Wie lesbar bekommt man ihn überhaupt hin?
  14. *&  • Und was für Vor- und Nachteile haben die Alternativen?
  15. *&---------------------------------------------------------------------*
  16. *& Ideen für Algorithmen
  17. *&---------------------------------------------------------------------*
  18. *& CONVERT_WITH_OFFSET :
  19. *& Offset-Zeiger wandert von rechts in Fünferschritten durch den String
  20. *& Dies ist die natürlichste Implementierungs-Idee
  21. *& CONVERT_WITH_SHIFT  :
  22. *& Die Funktion shift_right( ) schiebt Fünferblöcke nach rechts
  23. *& CONVERT_WITH_REGEX  :
  24. *& Globaler Replace des Ausdrucks `(\S{1,5})` durch `$1 `,
  25. *& dabei die Gruppierung mit einer Vorausschau-Bedingung kontrollieren
  26. *&---------------------------------------------------------------------*
  27. report zz_digit_groups.
  28.  
  29.  
  30. field-symbols: <p_digits> type c.
  31.    " Nur für Algorithmen, die ein Typ-C-Feld benötigen
  32.    " Unterprogramm to_char generiert ein C-Feld dynamischer Länge
  33.  
  34. parameters: p_digits type string
  35.               default '212190109010077040007'
  36.               lower case. "(Es dürfte auch alles mit Buchstaben funktionieren)
  37.  
  38. selection-screen comment /35(82) result.
  39.  
  40.  
  41. selection-screen skip.
  42. parameters:
  43.   p_shift  radiobutton group 001 default 'X',
  44.   p_regex  radiobutton group 001,
  45.   p_offset radiobutton group 001.
  46.  
  47. at selection-screen output.
  48.   perform convert.
  49.  
  50. at selection-screen.
  51.   condense p_digits no-gaps.
  52.  
  53. form convert.
  54.   if p_offset eq 'X'.
  55.     perform convert_with_offset.
  56.   elseif p_regex eq 'X'.
  57.     perform convert_with_regex.
  58.   elseif p_shift eq 'X'.
  59.     perform convert_with_shift.
  60.   endif.
  61. endform.
  62.  
  63. form convert_with_offset.
  64.  
  65.   clear result.
  66.  
  67. * Idee: ein Zeiger wandert den String rückwärts in Fünferschritten
  68.   data(lv_offset) = strlen( p_digits ) - 5.
  69.   while lv_offset >= 0.
  70.     result = p_digits+lv_offset(5) && ` ` && result.
  71.     subtract 5 from lv_offset.
  72.   endwhile.
  73.  
  74.   result = condense(
  75.     substring( val = p_digits off = 0 len = 5 + lv_offset )
  76.     && ` ` && result
  77.   ).
  78.  
  79. endform.
  80.  
  81. form convert_with_shift.
  82.  
  83.   clear result.
  84.  
  85. * Idee: iterativ mit SHIFT 5 Stellen nach rechts schieben
  86. * Dieser Algorithmus konsumiert den Input
  87.  
  88.   data(lv_input) = p_digits.
  89.   while count_any_not_of( val = lv_input sub = ` ` ) >= 5.
  90.     result = substring_before(
  91.                val = lv_input
  92.                regex = `$`
  93.                len = 5 )
  94.            && ` ` && result.
  95.     lv_input = shift_right( val = lv_input places = 5 ).
  96.   endwhile.
  97.  
  98.   result = condense( lv_input && ` ` && result ).
  99.  
  100. endform.
  101.  
  102. form convert_with_regex.
  103.  
  104.   result = p_digits.
  105.  
  106. * Fünfergruppen mit dem Muster (\S{1,5}) finden und durch `$1 ` ersetzen
  107. * Die Vorausschau-Zusicherung kontrolliert die Gruppierung
  108.   replace all occurrences of regex
  109.     `(\S{1,5})(?=(\S{5})+\s*$)`
  110.     in result
  111.     with `$1 `.
  112.  
  113. endform.
  114.  
  115. * Falls für einen Algorithmus nötig, die eingegebene Ziffernfolge in ein Typ C-Feld der nötigen Länge verwandeln
  116. * War in den drei hier vorgestellten Lösungen nicht nötig
  117. form to_char.
  118.   data: lv_char type ref to data,
  119.         lv_len  type i.
  120.   lv_len = strlen( p_digits ).
  121.   create data lv_char type c length lv_len.
  122.   assign lv_char->* to <p_digits>.
  123.   <p_digits> = p_digits.
  124. endform.
Add Comment
Please, Sign In to add comment