-
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: 1 -> 6 - 36 group 1: <div class="card"> group 2: abcdex group 3: </div> Find: 11 ms found: 2 -> 54 - 84 group 1: <div class="card"> group 2: bsdfsd group 3: </div> Find: 11 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(*no) alloc(*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: 1 -> 6 - 36 DSPLY <div class="card">bsdfsd</div> DSPLY Found: 2 -> 54 - 84
-
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.
-
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(*no) alloc(*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(10) value; 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: 1 -> Pos 6 - 36 DSPLY <div class="card">abcdex</div> DSPLY <div class="card"> DSPLY abcdex DSPLY </div> DSPLY Found: 2 -> Pos 54 - 84 DSPLY <div class="card">bsdfsd</div> DSPLY <div class="card"> DSPLY bsdfsd DSPLY </div>
-
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.
-
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
-
Anbei das modifizierte Programm (JAVA in Copy-Strecke ausgelagert), damit es einfacher lesbar ist
PHP-Code:
ctl-opt dftactgrp(*no) alloc(*teraspace) main(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(10) value; 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);
//------------------------------------------------------------------//
-
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.
-
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
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
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
die LineFeeds nicht findet
Mit diesem Pattern funktioniert es - siehe www.regexr.com
PHP-Code:
(<div +class="card">)([\s\S]*?)(<\/div>)
aber
wird von den C-API's nicht unterstützt
Viele Grüße
Rainer
Similar Threads
-
By Ranger in forum NEWSboard Programmierung
Antworten: 14
Letzter Beitrag: 18-03-21, 17:15
-
By Xanas in forum NEWSboard Java
Antworten: 6
Letzter Beitrag: 24-08-15, 13:43
-
By chrisssiie in forum NEWSboard Programmierung
Antworten: 28
Letzter Beitrag: 28-08-13, 08:22
-
By Markus Ralf in forum IBM i Hauptforum
Antworten: 2
Letzter Beitrag: 29-09-01, 11:18
-
By schreibr in forum Intern - Hilfe - Feedback - Tests-Forum
Antworten: 3
Letzter Beitrag: 29-09-01, 11:13
Berechtigungen
- Neue Themen erstellen: Nein
- Themen beantworten: Nein
- You may not post attachments
- You may not edit your posts
-
Foren-Regeln
|
Erweiterte Foren Suche
Google Foren Suche
Forum & Artikel Update eMail
AS/400 / IBM i
Server Expert Gruppen
Unternehmens IT
|
Kategorien online Artikel
- Big Data, Analytics, BI, MIS
- Cloud, Social Media, Devices
- DMS, Archivierung, Druck
- ERP + Add-ons, Business Software
- Hochverfügbarkeit
- Human Resources, Personal
- IBM Announcements
- IT-Karikaturen
- Leitartikel
- Load`n`go
- Messen, Veranstaltungen
- NEWSolutions Dossiers
- Programmierung
- Security
- Software Development + Change Mgmt.
- Solutions & Provider
- Speicher – Storage
- Strategische Berichte
- Systemmanagement
- Tools, Hot-Tips
Auf dem Laufenden bleiben
|
Bookmarks