[NEWSboard IBMi Forum]
  1. #1
    Registriert seit
    Aug 2014
    Beiträge
    179

    Regex mit RPG und Java

    Hallo Kollegen,

    ich habe ein Java-Programm, das aus einer HTML-Seite bestimmte "div" findet.
    Das Pattern sieht so aus und hat drei Gruppen
    HTML-Code:
    (<div class=\"card\">)([\\s\\S]*?)(</div>)
    Das Java-Programm sieht so aus

    PHP-Code:
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;

    public class 
    Regex_Loop_1 {
        public static 
    void main(String[] args) {
            
    long t System.currentTimeMillis();
            
    String patternString "(<div class=\"card\">)([\\s\\S]*?)(</div>)";
            
            
    String text "</div><div class=\"card\">abcdex</div><div>sdfssdf</div>" +
                          
    "<div class=\"card\">bsdfsd</div></div>";

            
    Pattern pattern Pattern.compile(patternString);
            
    Matcher matcher pattern.matcher(text);

            
    System.out.println("Compile & Matcher " + (System.currentTimeMillis() - t) + " ms");
            
            
    int count 0;

            while(
    matcher.find()) {
                
    count++;
                
    System.out.println("found: " count " -> " matcher.start() + " - " matcher.end());
                
    System.out.println("group 1: " matcher.group(1));
                
    System.out.println("group 2: " matcher.group(2));
                
    System.out.println("group 3: " matcher.group(3));
                
    System.out.println("Find: " + (System.currentTimeMillis() - t) + " ms");
            }
        }

    und findet zwei Elemente in jeweils 3 groups

    PHP-Code:
    Compile Matcher 10 ms
    found
    -> 36
    group 1
    : <div class="card">
    group 2abcdex
    group 3
    : </div>
    Find11 ms
    found
    -> 54 84
    group 1
    : <div class="card">
    group 2bsdfsd
    group 3
    : </div>
    Find11 ms 
    Jetzt habe ich das in ein RPG implementiert und möchte dort genauso über einen Index auf die groups zugreifen.

    Dazu habe ich zwei Fragen:
    1) wie muss ich den Programmaufruf dcl-pr Group definieren, damit ich wie im Java- Programm den Index mitgeben kann: matcher.group(1)
    2) wie muss ich den Aufruf in RPG mit Index machen

    Mir ist schon klar, dass es auch mit SQL geht, aber in diesem Fall möchte ich es mit RPG & Java machen.

    PHP-Code:
             ctl-opt dftactgrp(*noalloc(*teraspace);
          
    //------------------------------------------------------------------//
          // Includes                                                         //
          //------------------------------------------------------------------//

          
    /include QSYSINC/QRPGLESRC,JNI

          
    //------------------------------------------------------------------//
          // Prototypes                                                       //
          //------------------------------------------------------------------//

             
    dcl-s   JAVA_String object(*JAVA:'java.lang.String');

             
    dcl-pr  newString   object(*JAVA:'java.lang.String')
                                 
    extproc(*JAVA:'java.lang.String':*constructor);
                      
    Value      varchar(1000000) const;
             
    end-pr;

             
    dcl-pr  getBytes    varchar(65535)
                                 
    extproc(*JAVA:'java.lang.String':'getBytes');
             
    end-pr;

             
    dcl-pr  Compile     object(*JAVA:'java.util.regex.Pattern')
                                 
    extproc(*JAVA:'java.util.regex.Pattern':
                                               
    'compile') static;
                      
    Pattern    like(JAVA_String);
             
    end-pr;

             
    dcl-pr  Matcher     object(*JAVA:'java.util.regex.Matcher')
                                 
    extproc(*JAVA:'java.util.regex.Pattern':'matcher');
                      
    String     object(*JAVA:'java.lang.CharSequence');
             
    end-pr;

             
    dcl-pr  Find        ind
                                 extproc
    (*JAVA:'java.util.regex.Matcher':'find');
             
    end-pr;

             
    dcl-pr  Start       int(10)
                                 
    extproc(*JAVA:'java.util.regex.Matcher':'start');
             
    end-pr;

             
    dcl-pr  End         int(10)
                                 
    extproc(*JAVA:'java.util.regex.Matcher':'end');
             
    end-pr;

             
    dcl-pr  Group       object(*JAVA:'java.lang.String')
                                 
    extproc(*JAVA:'java.util.regex.Matcher':'group');
          
    //xxx       Index      object(*JAVA:'java.lang.Integer') const;
             
    end-pr;

             
    dcl-s   RegExPattern object(*JAVA:'java.util.regex.Pattern');
             
    dcl-s   RegExMatcher object(*JAVA:'java.util.regex.Matcher');

          
    //------------------------------------------------------------------//
          // Variablen                                                        //
          //------------------------------------------------------------------//

             
    dcl-s   RegPattern  like(JString);
             
    dcl-s   RegString   like(JString);
             
    dcl-s   RegResult   like(JString);

             
    dcl-s   LocPattern  varchar(256);
             
    dcl-s   LocString   varchar(256);
             
    dcl-s   LocInd      int(10);
             
    dcl-s   LocResult   varchar(50);
             
    dcl-s   LocGroup1   varchar(50);
             
    dcl-s   LocGroup2   varchar(50);
             
    dcl-s   LocGroup3   varchar(50);

               
    LocPattern '(<div class="card">)([\s\S]*?)(</div>)';

               
    LocString  '</div><div class="card">abcdex</div>' +
                            
    '<div>sdfssdf</div>' +
                            
    '<div class="card">bsdfsd</div></div>'


               
    RegPattern newString(LocPattern);
               
    RegString  newString(LocString);

               
    RegExPattern Compile(RegPattern);
               
    RegExMatcher Matcher(RegExPattern:RegString);

               
    dow Find(RegExMatcher) = *on;
                 
    RegResult Group(RegExMatcher);
                 
    LocResult getBytes(RegResult);

                 
    dsply (%subst(LocResult:1:30));

                 
    LocInd += 1;
                 
    dsply ('Found: ' + %char(LocInd) + ' -> '  +
                         %
    char(Start(RegExMatcher)) + ' - ' +
                         %
    char(End(RegExMatcher)));
               
    enddo;

               *
    inlr = *on
    Ergebnis

    PHP-Code:
      DSPLY  <div class="card">abcdex</div>  
     
    DSPLY  Found-> 36              
     DSPLY  
    <div class="card">bsdfsd</div>  
     
    DSPLY  Found-> 54 84 

  2. #2
    Registriert seit
    Feb 2001
    Beiträge
    20.207
    Statt Java nimm einfach SQL, das ist einfach mit dem Aufruf.
    https://www.itjungle.com/2015/05/19/fhg051915-story01/

    Das gibte mit irgendeiner Installations-Option und ist schneller als den aufwändigen Umweg über Java.
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  3. #3
    Registriert seit
    Aug 2014
    Beiträge
    179
    mein Ziel war es die Performance zwischen JAVA und den Regex SQL Statements zu testen, weil es sich bei meiner Aufgabe um eine größere Datenmenge handelt und außerdem habe ich dann mehr Verständnis für JAVA.

    Mit etwas probieren habe ich selbst die Lösung gefunden, die ich euch nicht vorenthalten will

    PHP-Code:
             ctl-opt dftactgrp(*noalloc(*teraspace);
          
    //------------------------------------------------------------------//
          // Includes                                                         //
          //------------------------------------------------------------------//

          
    /include QSYSINC/QRPGLESRC,JNI

          
    //------------------------------------------------------------------//
          // Prototypes                                                       //
          //------------------------------------------------------------------//

             
    dcl-s   JAVA_String object(*JAVA:'java.lang.String');

             
    dcl-pr  newString   object(*JAVA:'java.lang.String')
                                 
    extproc(*JAVA:'java.lang.String':*constructor);
                      
    Value      varchar(1000000) const;
             
    end-pr;

             
    dcl-pr  getBytes    varchar(65535)
                                 
    extproc(*JAVA:'java.lang.String':'getBytes');
             
    end-pr;

             
    dcl-pr  Compile     object(*JAVA:'java.util.regex.Pattern')
                                 
    extproc(*JAVA:'java.util.regex.Pattern':
                                               
    'compile') static;
                      
    Pattern    like(JAVA_String);
             
    end-pr;

             
    dcl-pr  Matcher     object(*JAVA:'java.util.regex.Matcher')
                                 
    extproc(*JAVA:'java.util.regex.Pattern':'matcher');
                      
    String     object(*JAVA:'java.lang.CharSequence');
             
    end-pr;

             
    dcl-pr  Find        ind
                                 extproc
    (*JAVA:'java.util.regex.Matcher':'find');
             
    end-pr;

             
    dcl-pr  Start       int(10)
                                 
    extproc(*JAVA:'java.util.regex.Matcher':'start');
             
    end-pr;

             
    dcl-pr  End         int(10)
                                 
    extproc(*JAVA:'java.util.regex.Matcher':'end');
             
    end-pr;

             
    dcl-pr  Group       object(*JAVA:'java.lang.String')
                                 
    extproc(*JAVA:'java.util.regex.Matcher':'group');
                      
    Index      int(10value;
             
    end-pr;

             
    dcl-s   RegExPattern object(*JAVA:'java.util.regex.Pattern');
             
    dcl-s   RegExMatcher object(*JAVA:'java.util.regex.Matcher');

          
    //------------------------------------------------------------------//
          // Variables                                                        //
          //------------------------------------------------------------------//

             
    dcl-s   RegPattern  like(JString);
             
    dcl-s   RegString   like(JString);

             
    dcl-s   LocPattern  varchar(256);
             
    dcl-s   LocString   varchar(256);
             
    dcl-s   LocInd      int(10);

             
    dcl-s   LocGroup0   char(50);
             
    dcl-s   LocGroup1   char(50);
             
    dcl-s   LocGroup2   char(50);
             
    dcl-s   LocGroup3   char(50);

               
    LocPattern '(<div class="card">)([\s\S]*?)(</div>)';

               
    LocString  '</div><div class="card">abcdex</div>' +
                            
    '<div>sdfssdf</div>' +
                            
    '<div class="card">bsdfsd</div></div>';

               
    RegPattern newString(LocPattern);
               
    RegString  newString(LocString);

               
    RegExPattern Compile(RegPattern);
               
    RegExMatcher Matcher(RegExPattern:RegString);

               
    dow Find(RegExMatcher) = *on;
                 
    LocInd += 1;
                 
    dsply ('Found: ' + %char(LocInd) + ' -> '  +
                         %
    char(Start(RegExMatcher)) + ' - ' +
                         %
    char(End(RegExMatcher)));

                 
    LocGroup0 getBytes(Group((RegExMatcher):0));
                 
    LocGroup1 getBytes(Group((RegExMatcher):1));
                 
    LocGroup2 getBytes(Group((RegExMatcher):2));
                 
    LocGroup3 getBytes(Group((RegExMatcher):3));

                 
    dsply (%subst(LocGroup0:1:30));
                 
    dsply (%subst(LocGroup1:1:30));
                 
    dsply (%subst(LocGroup2:1:30));
                 
    dsply (%subst(LocGroup3:1:30));

               
    enddo;

               *
    inlr = *on
    Ergebnis

    PHP-Code:
    DSPLY  Found-> Pos 6 36                
    DSPLY  
    <div class="card">abcdex</div>    
    DSPLY  <div class="card">                
    DSPLY  abcdex                            
    DSPLY  
    </div>                            
    DSPLY  Found-> Pos 54 84               
    DSPLY  
    <div class="card">bsdfsd</div>    
    DSPLY  <div class="card">                
    DSPLY  bsdfsd                            
    DSPLY  
    </div

  4. #4
    Registriert seit
    Feb 2001
    Beiträge
    20.207
    Ich denke schon, dass SQL schneller ist als RPGJAVA, da die JVM und Interjob-Kommunikation benötigt wird.
    Aber die Messergebnisse kannst du ja mal bereitstellen.
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  5. #5
    Registriert seit
    Aug 2014
    Beiträge
    179
    Jetzt liegen die Meßergebnisse vor und sind sehr überraschend. Zunächst die Basisdaten für meine Messung

    - IBM i Modell 914 Power 9, 2 Prozessoren, NVMe Speicher, 7.4
    - HTML Datei 160 KB im IFS
    - Das Ergebnis des Regex Patterns kommt in der HTML-Datei 21 Mal vor

    HTML-Code:
    (<div class=\"d-flex justify-content-between\">)
    ([\s\S]*?)(<div class=\"subtitle\">)([\s\S]*?)(</div>)
    ([\s\S]*?)(<div>)([\s\S]*?)(</div>)

    Messergebnisse mit SQL REGEXP_SUBSTR

    - 8 Sek

    Messergebnisse mit JAVA

    - 0,4 Sek - davon 0,3 Sek zum Laden der JVM

  6. #6
    Registriert seit
    Aug 2014
    Beiträge
    179
    Anbei das modifizierte Programm (JAVA in Copy-Strecke ausgelagert), damit es einfacher lesbar ist

    PHP-Code:
             ctl-opt dftactgrp(*noalloc(*teraspacemain(main);
          
    //------------------------------------------------------------------//
          //                                                                  //
          // Test - Regex with JAVA                                           //
          //                                                                  //
          //-----------------                                                 //
          // R.Ross 11.2021 *                                                 //
          //------------------------------------------------------------------//
          // Prototypes                                                       //
          //------------------------------------------------------------------//

          
    /include QSYSINC/QRPGLESRC,JNI
          
    /include DEVS/QCPYSRC,REGEXJAVA

          
    //------------------------------------------------------------------//
          // Main                                                             //
          //------------------------------------------------------------------//
             
    dcl-proc main;

             
    dcl-s   LocPattern  varchar(256);
             
    dcl-s   LocString   varchar(256);

             
    dcl-s   LocGroup0   char(50);
             
    dcl-s   LocGroup1   char(50);
             
    dcl-s   LocGroup2   char(50);
             
    dcl-s   LocGroup3   char(50);

               
    LocPattern   '(<div class="card">)([\s\S]*?)(</div>)';

               
    LocString    '</div><div class="card">abcdex</div>' +
                              
    '<div>sdfssdf</div>' +
                              
    '<div class="card">bsdfsd</div></div>';

               
    RegPattern   newString(LocPattern);
               
    RegString    newString(LocString);

               
    RegExMatcher Matcher(Compile(RegPattern):RegString);

               
    dow Find(RegExMatcher) = *on;
                 
    LocGroup0 getBytes(Group((RegExMatcher):0));
                 
    LocGroup1 getBytes(Group((RegExMatcher):1));
                 
    LocGroup2 getBytes(Group((RegExMatcher):2));
                 
    LocGroup3 getBytes(Group((RegExMatcher):3));
               
    enddo;

             
    end-proc;
          
    //------------------------------------------------------------------// 
    und die Copy-Strecke

    PHP-Code:
          //------------------------------------------------------------------//
          // JAVA String 1 MB                                                 //
          //------------------------------------------------------------------//

             
    dcl-pr  newString   like(JAVA_String)
                                 
    extproc(*JAVA:'java.lang.String':*constructor);
                      
    Value      varchar(1000000) const;
             
    end-pr;

          
    //------------------------------------------------------------------//
          // Get Bytes                                                        //
          //------------------------------------------------------------------//

             
    dcl-pr  getBytes    varchar(100000)
                                 
    extproc(*JAVA:'java.lang.String':'getBytes');
             
    end-pr;

          
    //------------------------------------------------------------------//
          // Regex Compile                                                    //
          //------------------------------------------------------------------//

             
    dcl-pr  Compile     object(*JAVA:'java.util.regex.Pattern')
                                 
    extproc(*JAVA:'java.util.regex.Pattern':
                                               
    'compile') static;
                      
    Pattern    like(JAVA_String);
             
    end-pr;

          
    //------------------------------------------------------------------//
          // Regex Matcher                                                    //
          //------------------------------------------------------------------//

             
    dcl-pr  Matcher     object(*JAVA:'java.util.regex.Matcher')
                                 
    extproc(*JAVA:'java.util.regex.Pattern':'matcher');
                      
    String     object(*JAVA:'java.lang.CharSequence');
             
    end-pr;

          
    //------------------------------------------------------------------//
          // Regex Matches                                                    //
          //------------------------------------------------------------------//

             
    dcl-pr  Matches     ind
                                 extproc
    (*JAVA:'java.util.regex.Matcher':'matches');
             
    end-pr;

          
    //------------------------------------------------------------------//
          // Regex Find                                                       //
          //------------------------------------------------------------------//

             
    dcl-pr  Find        ind
                                 extproc
    (*JAVA:'java.util.regex.Matcher':'find');
             
    end-pr;

          
    //------------------------------------------------------------------//
          // Regex Start Position from Find                                   //
          //------------------------------------------------------------------//

             
    dcl-pr  Start       int(10)
                                 
    extproc(*JAVA:'java.util.regex.Matcher':'start');
             
    end-pr;

          
    //------------------------------------------------------------------//
          // Regex End   Position from Find                                   //
          //------------------------------------------------------------------//

             
    dcl-pr  End         int(10)
                                 
    extproc(*JAVA:'java.util.regex.Matcher':'end');
             
    end-pr;

          
    //------------------------------------------------------------------//
          // Regex Group                                                      //
          //------------------------------------------------------------------//

             
    dcl-pr  Group       object(*JAVA:'java.lang.String')
                                 
    extproc(*JAVA:'java.util.regex.Matcher':'group');
                      
    Index      int(10value;
             
    end-pr;

          
    //------------------------------------------------------------------//
          // Variables                                                        //
          //------------------------------------------------------------------//

             
    dcl-s   JAVA_String  object(*JAVA:'java.lang.String');

             
    dcl-s   RegExPattern object(*JAVA:'java.util.regex.Pattern');
             
    dcl-s   RegExMatcher object(*JAVA:'java.util.regex.Matcher');

             
    dcl-s   RegPattern   like(JString);
             
    dcl-s   RegString    like(JString);

          
    //------------------------------------------------------------------// 

  7. #7
    Registriert seit
    Feb 2001
    Beiträge
    20.207
    Na, dann ist das ja eine fürterliche Implementation der Aufrufe.
    Irgendwo war hier mal der native Aufruf der C-Funktionen gemacht worden.
    Ggf. sind die ja noch schneller.
    Das damalige Problem war nur die Umgebung per Locale-Objekt, da die API's sonst immer per CCSID 037 per Default gearbeitet haben.
    Ich finde allerdings den Beitrag nicht mehr.
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  8. #8
    Registriert seit
    Aug 2014
    Beiträge
    179
    Deine Idee mit den C-Funktionen ist gut und ich habe es zuerst damit probiert und auch dass Pattern mit iconv in die CCSID 037 convertiert.

    Aber die C-Funktionen unterstützen bestimmte Patterns nicht und das habe ich nicht lösen können

    Pattern:
    HTML-Code:
    (<div class="card">)(</div>)
    funktioniert

    aber wenn im String zwischen "div" und "class" mehrere Leerzeichen sind, dann muss ich mit

    Pattern:
    HTML-Code:
    (<div+\s+class="card">)(<\/div>)
    arbeiten

    und hier bekomme ich bei den C-API's kein Ergebnis


  9. #9
    Registriert seit
    Nov 2020
    Beiträge
    315
    Hallo Rainer,

    funktioniert nicht folgender Code:
    PHP-Code:
    (<div +class="card">)(<\/div>) 
    Btw wenn du div+... schreibst, dann heißt das Plus nach dem "v", dass das v 1-n mal vorkommen darf.
    Hat dir bis jetzt kein Fehler geworfen, da es zufällig immer gepasst hat.

    lg Andreas

  10. #10
    Registriert seit
    Aug 2014
    Beiträge
    179
    Hallo Andreas,
    danke für den Tipp. Er funktioniert.

    Die Aufgabe ist leider komplexer, denn ich habe folgenden String
    PHP-Code:
    </div><div  class="card">asdfsadfsdf</div><div class="card">bsdfsdf</div
    und möchte die Daten zwischen den div's

    Mit diesem Pattern funktioniert es mit den C-API's
    PHP-Code:
    (<div +class="card">)(.*?)(<\/div>) 
    hat aber den Haken, dass
    PHP-Code:
    (.*?) 
    die LineFeeds nicht findet

    Mit diesem Pattern funktioniert es - siehe www.regexr.com
    PHP-Code:
    (<div +class="card">)([\s\S]*?)(<\/div>) 
    aber
    PHP-Code:
    ([\s\S]*?) 
    wird von den C-API's nicht unterstützt

    Viele Grüße
    Rainer

Similar Threads

  1. RegEx, um RPG Fixed Form zu erkennen
    By Ranger in forum NEWSboard Programmierung
    Antworten: 14
    Letzter Beitrag: 18-03-21, 18:15
  2. Java 8
    By Xanas in forum NEWSboard Java
    Antworten: 6
    Letzter Beitrag: 24-08-15, 14:43
  3. REGEX - CCSID???
    By chrisssiie in forum NEWSboard Programmierung
    Antworten: 28
    Letzter Beitrag: 28-08-13, 09:22
  4. VA RPG + JAVA
    By Markus Ralf in forum IBM i Hauptforum
    Antworten: 2
    Letzter Beitrag: 29-09-01, 12:18
  5. Java
    By schreibr in forum Intern - Hilfe - Feedback - Tests-Forum
    Antworten: 3
    Letzter Beitrag: 29-09-01, 12:13

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • You may not post attachments
  • You may not edit your posts
  •