Zugriff auf einfangende Klammern in der RegEx Engine

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
NicknameFJ
Beiträge: 324
Registriert: 03.06.2007 14:36
Wohnort: Von der Sonne aus gesehen der dritte Planet

Zugriff auf einfangende Klammern in der RegEx Engine

Beitrag von NicknameFJ »

Hallo zusammen,

der Titel ist etwas verwirrend, aber hier eine Umschreibung meines Problemes:

Ich bin am Entwicklen einer kaufmännischen Anwendung. Die Daten sind die einzelnen Buchungssätze im Buchhaltungssystem.

Ich möchte dem Benutzer die Möglichkeit geben die Daten (insbes. Buchungstexte) u.a. mit einer RegEx zu überprüfen um hiermit die gewünschten Buchungssätze zu selektieren und mit Hilfe meiner Anwendung weiter zu verarbeiten.

Die Buchungstexte haben kein einheitliches Format, der Benutzer entscheidet daher individuell nach welchen Kriterien die Buchungstexte untersucht werden. Die RegEx wird daher vom Benutzer frei eingegeben.

Gegeben sei daher ein Beispieltext "bla bla blubb abc123abc weiteres bla bla"

Die vom Benutzer eingegebene RegEx soll lauten:

Code: Alles auswählen

([a-z]{3})[0-9]{3}\1
Der von der RegEx zurückgegebene Treffer ist hierbei abc123abc.

Zur weiteren Verarbeitung möchte ich dem Benutzer die Möglichkeit geben auf die Inhalte der im RegEx enthaltenen einfangenden Klammern zuzugreifen. Die einfangende Klammer #1 hat im obigen Beispiel den Inhalt "abc".

Ein Zugriff über

Code: Alles auswählen

left(String$,3)
scheidet aus da die von der RegEx-Engine zurückgegebenen Datenstrings variieren, je nachdem welchen individuellen RegEx der Benutzer eingibt. Evtl. möchte der Benutzer auch auf andere einfangende Klammern zugreifen. Dies wird ja wie oben geschildert, ja nach konkreten Daten indiv. vom Benutzer entschieden.

Meine Frage daher:
Wie kann ich auf die von der RegEx-Engine gebildeten Inhalte der einfangenden Klammern zugreifen? Evtl. auch unter Umgehung der PureBasic RegEx-Funktionen und durch Verwendung über die PCRE-Library dll wenn es den so geht. Wenn es nur über die externe dll geht bräuchte ich einen Beispielcode da ich noch nicht direkt mit dieser Library gearbeitet habe.

Ich hoffe es ist irgendwie verständlich was ich will.

Bin für jede Anregung dankbar.

NicknameFJ
Zuletzt geändert von NicknameFJ am 16.01.2012 20:28, insgesamt 1-mal geändert.
PS: Alle im Text enthaltenen Schreibfehler sind beabsichtigt und dienen der Belustigung aller

Bild
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Re: Zugriff auf einfangende Klammern in der RegEx Engine

Beitrag von edel »

Vielleicht hilft dir das hier weiter :

Code: Alles auswählen

ImportC ""
  pcre_exec(*pcre, *extra, subject.s, length, startoffset, options, *ovector, ovecsize)
  pcre_get_substring(subject.s, *ovector, stringcount, stringnumber, *stringptr)
  pcre_free_substring(*stringptr)
EndImport

subject.s = "bla bla blubb abc123abc weiteres bla bla"
pattern.s = "([a-z]{3})[0-9]{3}\1"
len = Len(subject)
offset = 0
first_sub = 0
count = 0

Dim ovec(30)

regex = CreateRegularExpression(#PB_Any, pattern)

count = pcre_exec(PeekL(regex), 0, subject, len, offset, 0, @ovec(), 30)

While count>0
  
  pcre_get_substring(subject, ovec(), count, 1, @first_sub)
  
  Debug PeekS(first_sub)
    
  pcre_free_substring(first_sub)
  
  offset = ovec(1)
  count = pcre_exec(PeekL(regex), 0, subject, len, offset, 0, @ovec(), 30)
Wend
Benutzeravatar
NicknameFJ
Beiträge: 324
Registriert: 03.06.2007 14:36
Wohnort: Von der Sonne aus gesehen der dritte Planet

Re: Zugriff auf einfangende Klammern in der RegEx Engine

Beitrag von NicknameFJ »

Hi Edel,

danke, das ist genau das wonach ich gesucht habe.


Grüße

NicknameFJ
PS: Alle im Text enthaltenen Schreibfehler sind beabsichtigt und dienen der Belustigung aller

Bild
Benutzeravatar
NicknameFJ
Beiträge: 324
Registriert: 03.06.2007 14:36
Wohnort: Von der Sonne aus gesehen der dritte Planet

Re: Zugriff auf einfangende Klammern in der RegEx Engine

Beitrag von NicknameFJ »

Hallo,

Ich habe inzwischen auf PB 4.61 updated. Das Beispiel von Edel mit IMPORTC kann mit 4.61 nicht mehr kompiliert werden. Der Compiler wirft folgenden Fehler

Code: Alles auswählen

---------------------------
PureBasic - Linker error
---------------------------
POLINK: error: Unresolved external symbol '_pcre_exec'.

POLINK: error: Unresolved external symbol '_pcre_get_substring'.

POLINK: error: Unresolved external symbol '_pcre_free_substring'.

POLINK: fatal error: 3 unresolved external(s).


---------------------------
OK   
---------------------------
Kann das jemand bestätigen? Oder liegt ein Problem mit meiner Installation vor? Ich habe 4.61 eigentlich sauber in ein neues Verzeichnis installiert!

Grüße

NicknameFJ
PS: Alle im Text enthaltenen Schreibfehler sind beabsichtigt und dienen der Belustigung aller

Bild
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Zugriff auf einfangende Klammern in der RegEx Engine

Beitrag von STARGÅTE »

Den Error kann ich bestätigen, aber ist auch nicht verwunderlich,
denn es wird ja irgendwas eingeladen und benutzt, was nicht offiziell von PB dokumentiert ist.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
NicknameFJ
Beiträge: 324
Registriert: 03.06.2007 14:36
Wohnort: Von der Sonne aus gesehen der dritte Planet

Re: Zugriff auf einfangende Klammern in der RegEx Engine

Beitrag von NicknameFJ »

Danke Stargate für Deine Bestätigung.

Ich kenne mich mit dem Import-Zeug nicht so aus. Aber es hat für mich, dank Deiner Besstätigung dass es bei Dir auch den Fehler wirft, den Eindruck, dass der Linker die importierten Funktionen aus der LIB nicht findet. Lt. PB Hilfe zu den RegEx mit Link http://www.pcre.org/pcre.txt findet sich eine Liste mit den in der LIB enthaltenen Funktionen. Die dort aufgeführten Funktionen (für 8-BIT) haben genau die Namen die auch im Programm importiert werden. Es sieht dann so aus als ob die genannten Funktionen beim compilieren (des Compilers durch Fred) von PB 4.61 nicht mehr als public deklariert wurden oder so ähnlich. Ich kann mich vage an eine Aussage oder Änderung in PB erinnern dass ab einer Version (evtl. 4.61) eine neue Version der PCRE-Lib verwendet wird.

Vielleicht hat ja noch jemand anders eine Idee wie ich die Funktion in mein Programm einbinden kann.

BTW: MIt PB 4.71B1 wirft es den selben Fehler.

Wäre echt schade wenn ich mein Projekt nicht mit 4.61 und folgende weiterführen könnte sondern bei 4.60 stehen bleiben müsste.

Grüße

NicknameFJ
PS: Alle im Text enthaltenen Schreibfehler sind beabsichtigt und dienen der Belustigung aller

Bild
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Re: Zugriff auf einfangende Klammern in der RegEx Engine

Beitrag von Danilo »

NicknameFJ hat geschrieben:Hallo,

Ich habe inzwischen auf PB 4.61 updated. Das Beispiel von Edel mit IMPORTC kann mit 4.61 nicht mehr kompiliert werden. Der Compiler wirft folgenden Fehler

Code: Alles auswählen

---------------------------
PureBasic - Linker error
---------------------------
POLINK: error: Unresolved external symbol '_pcre_exec'.
POLINK: error: Unresolved external symbol '_pcre_get_substring'.
POLINK: error: Unresolved external symbol '_pcre_free_substring'.
POLINK: fatal error: 3 unresolved external(s).
---------------------------
OK   
---------------------------
Du musst nun ein "pb_" vor die Import-Namen setzen, siehe POLINK error with pcre & PB4.61.

Code: Alles auswählen

ImportC ""
  pb_pcre_exec(*pcre, *extra, subject.p-ascii, length, startoffset, options, *ovector, ovecsize)
  pb_pcre_get_substring(subject.p-ascii, *ovector, stringcount, stringnumber, *stringptr)
  pb_pcre_free_substring(*stringptr)
EndImport

subject.s = "bla bla blubb abc123abc weiteres bla bla"
pattern.s = "([a-z]{3})[0-9]{3}\1"
len = Len(subject)
offset = 0
first_sub = 0
count = 0

Dim ovec(30)

regex = CreateRegularExpression(#PB_Any, pattern)

count = pb_pcre_exec(PeekL(regex), 0, subject, len, offset, 0, @ovec(), 30)

While count>0
  
  pb_pcre_get_substring(subject, ovec(), count, 1, @first_sub)
  
  Debug PeekS(first_sub,-1,#PB_Ascii)
    
  pb_pcre_free_substring(first_sub)
  
  offset = ovec(1)
  count = pb_pcre_exec(PeekL(regex), 0, subject, len, offset, 0, @ovec(), 30)
Wend

Oder Du nimmst ts-softs methode (aber mit p-ascii für .s), dann bleiben die Namen gleich.

Code: Alles auswählen

;
; http://forums.purebasic.com/german/viewtopic.php?f=3&t=25124
;
; by edel
;
;
; POLINK error with pcre & PB4.61:
; http://www.purebasic.fr/english/viewtopic.php?f=13&t=50040
;
ImportC ""
    CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
        ;
        ; eats all memory on x64 -> reboot warning
        ;
        ;pcre_exec(*pcre, *extra, subject.p-ascii, length, startoffset, options, *ovector, ovecsize) As "pb_pcre_exec"
        ;pcre_get_substring(subject.p-ascii, *ovector, stringcount, stringnumber, *stringptr)        As "pb_pcre_get_substring"
        ;pcre_free_substring(*stringptr)                                                             As "pb_pcre_free_substring"
    CompilerElse
        pcre_exec(*pcre, *extra, subject.p-ascii, length, startoffset, options, *ovector, ovecsize) As "_pb_pcre_exec"
        pcre_get_substring(subject.p-ascii, *ovector, stringcount, stringnumber, *stringptr)        As "_pb_pcre_get_substring"
        pcre_free_substring(*stringptr)                                                             As "_pb_pcre_free_substring"
    CompilerEndIf
EndImport

subject.s = "bla bla blubb abc123abc weiteres bla bla"
pattern.s = "([a-z]{3})[0-9]{3}\1"
len = Len(subject)
offset = 0
first_sub = 0
count = 0

Dim ovec(30)

regex = CreateRegularExpression(#PB_Any, pattern)

count = pcre_exec(PeekL(regex), 0, subject, len, offset, 0, @ovec(), 30)

While count>0
  
  pcre_get_substring(subject, ovec(), count, 1, @first_sub)
  
  Debug PeekS(first_sub,-1,#PB_Ascii)
    
  pcre_free_substring(first_sub)
  
  offset = ovec(1)
  count = pcre_exec(PeekL(regex), 0, subject, len, offset, 0, @ovec(), 30)
Wend
Auf 64bit frisst das hier allerdings den ganzen Speicher, ist wohl noch ein Fehler drin.
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Benutzeravatar
NicknameFJ
Beiträge: 324
Registriert: 03.06.2007 14:36
Wohnort: Von der Sonne aus gesehen der dritte Planet

Re: Zugriff auf einfangende Klammern in der RegEx Engine

Beitrag von NicknameFJ »

Danke Dir Danilo.

Grüße

NicknameFJ
PS: Alle im Text enthaltenen Schreibfehler sind beabsichtigt und dienen der Belustigung aller

Bild
Benutzeravatar
Kukulkan
Beiträge: 1066
Registriert: 09.09.2004 07:07
Wohnort: Süddeutschland
Kontaktdaten:

Re: Zugriff auf einfangende Klammern in der RegEx Engine

Beitrag von Kukulkan »

http://www.purebasic.fr/english/viewtop ... =3&t=51054

Bitte mit +1 kommentieren. Evtl. liest es Fred ja...
Antworten