![]() |
Regex geht nicht mehr?
Hallo ich bin es mal wieder! :lol:
Delphi-Quellcode:
So also mein Problem ist das wenn der Reguläre ausdruck korrekt ist macht er ein "Zugriffsverletzung" in der Klasse EAccessViolation :?:... uses perlregex; {$R *.dfm} function verarbeitung(code:array of string;pos:array of integer):string; var i:integer; begin for i := 0 to length(code) do result := result + '|' + code[i] + ','; end; function regl(subj, expr: string): string; var code:array of string; pos:array of integer; begin with TPerlRegEx.Create(nil) do begin RegEx := expr; Subject := subj; if Match = false then begin // repeat // code[SubExpressionCount] := SubExpressions[SubExpressionCount]; //geändert! until MatchAgain // aber wo is hier der fehler? end; // result := verarbeitung(code,pos); // end; end; procedure TForm3.Button1Click(Sender: TObject); begin edit1.Text:=regl(edit2.Text,'<*>'); //<-------- Fehler end; ... Gestern abend ging es noch und wo ich dann danach noch was geändert hab (siehe oben) war es tot! hab schon die ganze zeit gesucht und hab das auch noch die funktion verklienert aber es geht immer noch nicht!Wo ist der Fehler(hab schon mir eine kleine Fehlerquelle erahnt)? danke für antworten! (ich hab garantiert was falsch gemacht :pale: ) |
Re: Regex geht nicht mehr?
SubExpressions dürfte von 0 bis SubExpressionCount - 1 indiziert sein.
Du gibst außerdem das erstellte TPerlRegEx nicht wieder frei, erzeugst also bei jedem Aufruf ein Speicherleck. Weiterhin sollte man Boolean Werte nicht auf "= False" prüfen, sondern mit "not Wert". |
Re: Regex geht nicht mehr?
Ohne die Klasse zu kennen, fällt mir folgendes auf:
- das Integer-Array wird nirgends benutzt. - die Länge des String-Arrays wird nicht gesetzt (SetLength) - 0 bis Length kann ja nicht stimmen |
Re: Regex geht nicht mehr?
wie kann ich die länge eines arrays bestimmen?
Delphi-Quellcode:
length(code) //stimmt ja nicht
|
Re: Regex geht nicht mehr?
Doch, Length() gibt Dir die Länge zurück. Aber da dynamische Arrays immer 0-indiziert sind, hat das letzte Element den Index Length - 1. Ich selbst habe mir angewöhnt, über Arrays immer mit Low() und High() zu iterieren, dann kann nichts passieren.
|
Re: Regex geht nicht mehr?
Delphi-Quellcode:
danke für die tipps
function verarbeitung(code:array of string;pos:array of integer):string;
var i:integer; begin for i := 0 to high(code) do result := result + code[i] + '|' + ','; end; function regl(subj, expr: string): string; var code:array of string; pos:array of integer; begin with TPerlRegEx.Create(nil) do begin RegEx := expr; Subject := subj; if Match then begin repeat setlength(code,SubExpressionCount-1); code[SubExpressionCount-1] := SubExpressions[SubExpressionCount-1]; until MatchAgain end; result := verarbeitung(code,pos); end; TPerlRegEx.free; end; Die pos array will ich dann später noch einbinden. Hab jetzt soweit alles geändert aber bei den Tperlregex.free will das nicht so gehen. warum? |
Re: Regex geht nicht mehr?
Du willst eine Klasse freigeben und keine Instanz. Also brauchst Du entweder eine Variable oder Du schreibst das in der Art
Delphi-Quellcode:
[edit] Schreibfehler [/edit]
with TPerlRegEx.Create(nil) do
try //Code finally Free; end; |
Re: Regex geht nicht mehr?
so jetzt kommt ein fehler "Fehler bei Bereichsprüfung" in der Gleichen Zeile ?
Was soll den das sein? :gruebel: Hat das irgend was mit meinem Regulären Ausdruck zu tun? Ich bin mir eigend lich sicher das dass so richtig ist(denken kann man viel :wink: ). |
Re: Regex geht nicht mehr?
Delphi-Quellcode:
Ohne "-1". Das Array hat eine Länge von "SubExpressionCount" und der Indizierung geht von 0 an bis SubExpressionCount - 1. (Genauso wie bei SubExpressions[]).
setlength(code,SubExpressionCount);
|
Re: Regex geht nicht mehr?
wenn ich dort das weg mache kommt wieder der feher wie oben? :?:
|
Re: Regex geht nicht mehr?
Nochmal zum Verständnis:
Delphi-Quellcode:
[edit] Oder mal zum Angucken:
var Wuppdi: array of TBlubb;
... SetLength(Wuppdi,3); //Länge auf 3 Elemente setzen ShowMessage(IntToStr(Low(Wuppdi))); //ist bei dynamischen Arrays immer 0 ShowMessage(IntToStr(High(Wuppdi))); //ergibt 2, d.h. Index des letzten Elements
Delphi-Quellcode:
var Bla: array of integer;
... SetLength(Bla,3); for i := Low(Bla) to High(Bla) do Bla[i] := 10;
Code:
[/edit]
| Index | 0 | 1 | 2 |
| Inhalt | 10 | 10 | 10 | |
Re: Regex geht nicht mehr?
Aber da ändert sich das porblem doch nicht?
Delphi-Quellcode:
(ist heut anscheinend nicht mein Tag!)
function verarbeitung(code:array of string;pos:array of integer):string;
var i:integer; begin for i := low(code) to high(code) do result := result + code[i] + '|' + ','; end; function regl(subj, expr: string): string; var code:array of string; pos:array of integer; begin with TPerlRegEx.Create(nil) do begin try RegEx := expr; Subject := subj; if Match then begin repeat setlength(code,SubExpressionCount); code[SubExpressionCount] := SubExpressions[SubExpressionCount]; until MatchAgain end; result := verarbeitung(code,pos); finally free; end; end; end; |
Re: Regex geht nicht mehr?
Delphi-Quellcode:
setlength(code,SubExpressionCount);
code[High(code)] := SubExpressions[High(SubExpressions)]; |
Re: Regex geht nicht mehr?
oh stimmt ich war noch oben in der schleife :wall:
mir ist das ja schon richtig beinlich :lol: :oops: :lol: aber das funktioniert immer noch nicht so wirklich irgend was stimmt immer noch nicht in der If-Anweisung ! :gruebel: |
Re: Regex geht nicht mehr?
ach und der mekert an der zeile
Delphi-Quellcode:
code[high(code)] := SubExpressions[High(Subexpressions)];
//heist das nicht SubexpressionCount? |
Re: Regex geht nicht mehr?
Achso, SubExpressions ist wohl kein dynamisches Array. Dann eben so:
Delphi-Quellcode:
code[High(code)] := SubExpressions[High(code)];
//oder code[SubExpressionCount - 1] := SubExpressions[SubExpressionCount - 1]; |
Re: Regex geht nicht mehr?
macht nichts!
das problem besteht immer noch ich bin mir wirklich sicher das nur hier irgendwo ein fehler ist weil immer wenn der Reg.Aus. wahr ist also wo If match ist true dann kommt der Fehler!(Bin am verzweifel :coder2: ) Hier nochmal mein ganzer Code:
Delphi-Quellcode:
unit Unit3;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm3 = class(TForm) Button1: TButton; Edit1: TEdit; Edit2: TEdit; procedure Button1Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form3: TForm3; implementation uses perlregex; {$R *.dfm} function verarbeitung(code:array of string;pos:array of integer):string; var i:integer; begin for i := low(code) to high(code) do result := result + code[i] + '|' + ','; end; function regl(subj, expr: string): string; var code:array of string; pos:array of integer; h:integer; begin with TPerlRegEx.Create(nil) do begin try RegEx := expr; Subject := subj; //A fehlerquelle meinermeinung nach if Match then begin repeat setlength(code,SubExpressionCount); code[High(code)] := SubExpressions[High(code)]; until MatchAgain; result := verarbeitung(code,pos); end; //B Ende finally free; end; end; end; procedure TForm3.Button1Click(Sender: TObject); begin edit1.Text:=regl(edit2.Text,'<*>'); end; procedure PatchINT3; var NOP : Byte; NTDLL: THandle; BytesWritten: DWORD; Address: Pointer; begin if Win32Platform <> VER_PLATFORM_WIN32_NT then Exit; NTDLL := GetModuleHandle('NTDLL.DLL'); if NTDLL = 0 then Exit; Address := GetProcAddress(NTDLL, 'DbgBreakPoint'); if Address = nil then Exit; try if Char(Address^) <> #$CC then Exit; NOP := $90; if WriteProcessMemory(GetCurrentProcess, Address, @NOP, 1, BytesWritten) and (BytesWritten = 1) then FlushInstructionCache(GetCurrentProcess, Address, 1); except //Do not panic if you see an EAccessViolation here, it is perfectly harmless! on EAccessViolation do ; else raise; end; end; initialization // nur wenn ein Debugger vorhanden, den Patch ausführen if DebugHook<>0 then PatchINT3; end. |
Re: Regex geht nicht mehr?
Schau doch mal im Debugger, was in SubExpressions und SubExpressionCount eigentlich drinsteht. Außer, dass Du in Verarbeitung Result nicht initialisierst, sehe ich im Moment keinen Fehler (es ist aber auch schon spät am Abend).
|
Re: Regex geht nicht mehr?
SubExpressions[Index: integer]:string;
SubExpressionCount : integer; Und wie meinst du das mit dem initialisieren des result! In verarbeitung ist doch alles soweit richtig?
Delphi-Quellcode:
function verarbeitung(code:array of string;pos:array of integer):string;
var i:integer; begin for i := low(code) to high(code) do result := result + code[i] + '|' + ','; end; |
Re: Regex geht nicht mehr?
Setz mal lieber als erste Zeile hinter das "begin"
Delphi-Quellcode:
[edit] Und ich meinte nicht die Definition, sondern zur Laufzeit nachschauen, was in den Feldern drin ist. [/edit]
Result := '';
|
Re: Regex geht nicht mehr?
Liste der Anhänge anzeigen (Anzahl: 1)
Hab mal ein Bild vom Programm gemacht
wenn man auf dem Button Oben Fehler meldung und unten Warnung beim Erzuegen. |
Re: Regex geht nicht mehr?
Setz doch mal einen Breakpoint, steppe durch und nenne mir die Zeile und Routine, in der der Fehler auftritt.
|
Re: Regex geht nicht mehr?
ich hab mal getestet und bin auf diese Zeile gekommen:
Delphi-Quellcode:
Sobald ich den Breackpoint dahinter setze bringt er den fehler wo ich davon ein bild gemacht hab.
54: code[High(code)] := SubExpressions[High(code)];
55: Breack until MatchAgain; |
Re: Regex geht nicht mehr?
Da ich die Klasse nicht kenne: kann sich SubExpressionCount innerhalb der Schleife ändern? Wenn nicht, setz das SetLength() mal vor die Schleife.
|
Re: Regex geht nicht mehr?
Ne das geht nicht weil ja SubExpressions Die "suchergebnisse" hat und das ist in einem Array gespeichter und ich will Die Daten in ein anderes Array Übertragen.
Hab das trotzdem gemacht funktioniert nicht. |
Re: Regex geht nicht mehr?
Da denke ich später nochmal drüber nach, ich muss jetzt in Bett.
|
Re: Regex geht nicht mehr?
ich auch tschau!
|
Re: Regex geht nicht mehr?
Guten Morgen,
Zitat:
Grüße, Uli |
Re: Regex geht nicht mehr?
Liste der Anhänge anzeigen (Anzahl: 1)
Delphi-Quellcode:
Also würde ich das so Copy/Paste machen dann funktionriet es auch nicht!
SetLength(code, 0); //Array initialisieren
with TPerlRegEx.Create(nil) do ... if Match then begin repeat nOldIndex := Length(code); setlength(code, nOldIndex + SubExpressionCount); // warum dann noch + SubExpressionCount for n := 0 to SubExpressionCount - 1 do code[nOldIndex + n] := SubExpressions[n]; // warum nicht nur n? until not MatchAgain; // heist das nicht so viel wie nächster treffer result := verarbeitung(code,pos); end; Positiv: Es kommt keine Fehlernmeldung Negativ: Es gib kein Ergebniss! Also hier mal ein Script das ich unter C# geschrieben hab:
Code:
Das blöde ist dass das nicht genauso ist wie in Delphi geht! :cry:
private void ... ;
{ MatchCollection mc; Match m; int[] count = new int[20]; int[] position = new int[20]; Regex r = new Regex("{(?<contents>[^}]*)}"); mc = r.Matches("{Text1} und {Text2}"); //Suchergebnisse in das vorgegebene Array Speichern for (int i = 0; i < mc.Count; i++) { count[i] = mc[i].Length; position[i] = mc[i].Index; } //auslesen der Arrays for (int i = 0; i < mc.Count; i++) { richTextBox1.Text += "Gefundene Position:" + position[i] + "\n"; richTextBox1.Text += "Länge vom String:" + count[i] + "\n"; } } Die MatchCollection (ist bestimmt mit in der Subexpressions eingebaut :gruebel: ) ist sehr hilfreich und der ganze aufbau halt! Aber so funktioiert das ja nicht in delphi! |
Re: Regex geht nicht mehr?
Ich denke mal, wenn Du eine for-Schleife nehmen würdest, bekämst Du auch ein Ergebnis.
|
Re: Regex geht nicht mehr?
Also:
1) Deine eingestellte RegEx findet nur Texte der Bauart: ein '<', gefolgt von einem beliebigen Zeichen, gefolgt von '>', also so was wie <t> aber nicht <tt>! 2) SubexpressionCount bezieht sich auf die Anzahl der Gruppierungsklammern des regulären Ausdrucks: bei '<.>' gibt es keine, also 0. Bei '<(.+)>' ist der Count = 1! 3) Was Du suchst ist MatchedExpression und zwar zusammen mit der Option UnGreedy (behaute ich einfach mal :mrgreen: ) Schau Dir mal den Code an, der läuft bei mir fein:
Delphi-Quellcode:
und zwar zusammen mit der RegEx '<.+>':
function regl(subj, expr: string): string;
var code: array of string; pos: array of integer; regexMachine: TPerlRegEx; begin SetLength(code, 0); //Array initialisieren regexMachine := TPerlRegEx.Create(nil); try regexMachine.RegEx := expr; regexMachine.Subject := subj; regexMachine.Options := regexMachine.Options + [preUnGreedy]; if regexMachine.Match then begin repeat setlength(code, Length(code) + 1); // Treffer um neu gefundenen erweitern code[Length(code) - 1] := regexMachine.MatchedExpression; // Neue Treffer in das code Array eintragen until not regexMachine.MatchAgain; // und weitersuchen. Abbruch, wenn kein Treffer mehr result := verarbeitung(code,pos); // jetzt ALLE Treffer verarbeiten end; finally regexMachine.free; end; end;
Delphi-Quellcode:
das liefert dann für den Text '<Test>er and <Test>s and <Sheep>++':
procedure TForm3.Button1Click(Sender: TObject);
begin edit1.Text := regl(edit2.Text, '<.+>'); // finde '<' gefolgt von einem oder mehreren beliebigen Zeichen gefolgt von '>' end; <Test>|,<Test>|,<Sheep>|, Grüße, Uli |
Re: Regex geht nicht mehr?
statt den Repeat...Until?
|
Re: Regex geht nicht mehr?
Uli hat doch bereits eine Lösung, schau Dir die mal an.
|
Re: Regex geht nicht mehr?
Hab ich auch gesehen war bloß zu schnell mit dem versenden! :wink:
Genau sowas hab ich gesucht (die lösung ist genial)! :thumb: vielen dank erstmal allen die mir Geholfen haben (DeddyH,ULIK)! Und jetzt zu der Pos. Wie bekomme ich die Position des Gefundenen Strings Raus? Wie in der C# gibt es ja den befehl
Code:
mc[i].Index;
|
Re: Regex geht nicht mehr?
Da gibt'S eine Property dafür: matchLength + matchstart glaub ich.
Uli |
Re: Regex geht nicht mehr?
Delphi-Quellcode:
Hab ich das falsch verstanden?
pos[Length(code) - 1] := regexMachine.matchedstart; // Warum ist das den Falsch
~~~~~~~~~~~~ |
Re: Regex geht nicht mehr?
ich hab mal ein bissel probiert.
Hab das jetzt gefunden! Die funktion für die Länge ist in Tperlregex:
Delphi-Quellcode:
Und die Positionbestimmen:
regexMachine.MatchedExpressionLength;
Delphi-Quellcode:
Hier noch mal der gesamte Quelltext (fehlerfrei!):
regexMachine.MatchedExpressionOffset;
Delphi-Quellcode:
function verarbeitung(code:array of string;pos:array of integer):string;
var i:integer; begin result:=''; for i := low(code) to high(code) do result := result + code[i] + '|' + inttostr(pos[i]) + ','; end; function regl(subj, expr: string): string; var code: array of string; pos: array of integer; regexMachine: TPerlRegEx; begin SetLength(code, 0); //Array initialisieren SetLength(pos, 0); // regexMachine := TPerlRegEx.Create(nil); try regexMachine.RegEx := expr; regexMachine.Subject := subj; regexMachine.Options := regexMachine.Options + [preUnGreedy]; if regexMachine.Match then begin repeat setlength(code, Length(code) + 1);// Treffer um neu gefundenen erweitern setlength(pos, Length(pos) + 1); // code[Length(code) - 1] := regexMachine.MatchedExpression;// Neue Treffer in das code Array eintragen pos[Length(code) - 1] := regexMachine.MatchedExpressionOffset - 1;//Position des Treffers until not regexMachine.MatchAgain; // und weitersuchen. Abbruch, wenn kein Treffer mehr result := verarbeitung(code,pos); // jetzt ALLE Treffer verarbeiten end; finally regexMachine.free; end; end; procedure TForm3.Button1Click(Sender: TObject); begin edit1.Text:=regl(edit2.Text,'<.+>'); end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:26 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz