AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

REGEX mit TMatchCollection

Ein Thema von wschrabi · begonnen am 25. Jul 2024 · letzter Beitrag vom 25. Jul 2024
Antwort Antwort
wschrabi

Registriert seit: 16. Jan 2005
442 Beiträge
 
#1

REGEX mit TMatchCollection

  Alt 25. Jul 2024, 10:24
Liebe Leute,
REGEX macht Probleme.
Hier mein CODE:

Delphi-Quellcode:
function Tform1.getGefkl(text: string): string;
var
  pattern,mainToken,subTokens: string;
  matches: TMatchCollection;
  match: TMatch;
begin

 text := 'ABSCHNITT 14: Angaben zum Transport'#13#10 +
          '14.1 UN-Nummer'#13#10 +
          'ADR/RID: 2735 IMDG: 2735 IATA: 2735'#13#10 +
          '14.2 Ordnungsgemäße UN-Versandbezeichnung'#13#10 +
          'ADR/RID: AMINE, FLÜSSIG, ÄTZEND, N.A.G. (3-Aminopropyltriethoxysilan) IMDG: AMINES, LIQUID, CORROSIVE, N.O.S. (Triethoxy(3-aminopropyl)silane) IATA: Amines, liquid, corrosive, n.o.s. (Triethoxy(3-aminopropyl)silane)'#13#10 +
          '14.3 Transportgefahrenklassen ADR/RID: 6.1 (3, 8)'#13#10 +
          '14.4 Verpackungsgruppe ADR/RID: II'#13#10 +
          '14.5 Umweltgefahren ADR/RID: nein'#13#10 +
          'IMDG: 8'#13#10 +
          'IMDG: II'#13#10 +
          'IMDG Meeresschadstoff: nein'#13#10 +
          'IATA: 8'#13#10 +
          'IATA: II';
          
  pattern := '(1|2|3|4\.1|4\.2|4\.3|5\.1|5\.2|6\.1|6\.2|7|8|9)(?:\s*\((1|2|3|4\.1|4\.2|4\.3|5\.1|5\.2|6\.1|6\.2|7|8|9(?:,\s*(1|2|3|4\.1|4\.2|4\.3|5\.1|5\.2|6\.1|6\.2|7|8|9))*)\))?';

 

  matches := TRegEx.Matches(text, pattern);

  if matches.Count > 0 then
  begin
    if match.Groups.Count>1 then
      begin
       for match in matches do
       begin
         mainToken := match.Groups[1].Value;
         subTokens := match.Groups[2].Value;
         if subTokens <> 'then
           Result:= mainToken+' ('+ subTokens+ ')'
         else
           Result:= mainToken;
       end;
      end;
  end
  else
  begin
    Result:='';
  end;
  Show_UpDate_LOG(clBLue,mymodeRUN,Format('Match:(%s ):COUNT:%d',[Result,matches.Count]));
  
  
end;
Die Counts der Gruppen sind immer 0!
AUch Sagt mir Perplexity.ai dass.

Ja, es gibt bekannte Probleme und Herausforderungen bei der Verwendung von regulären Ausdrücken und der Gruppenzählung in Delphi. Hier sind einige relevante Punkte, die in den Suchergebnissen und der allgemeinen Erfahrung mit Delphi hervorgehoben werden:

1. **Performance-Probleme mit regulären Ausdrücken**: Delphi XE4 bis Delphi 10.2 verwenden die UTF-8-Version von PCRE, obwohl PCRE bereits native UTF-16-Unterstützung hatte. Dies führt zu ständigen Konvertierungen zwischen UTF-16 und UTF-8, was die Leistung der regulären Ausdrücke insbesondere bei langen Zeichenfolgen erheblich beeinträchtigen kann[3].

2. **Probleme mit der Gruppenzählung**: Es gibt Berichte über Probleme mit der Gruppenzählung in Delphi, insbesondere wenn es um die Verwendung von regulären Ausdrücken geht. Dies kann auf die Art und Weise zurückzuführen sein, wie Delphi die PCRE-Bibliothek implementiert und verwendet[3].

3. **Komponenten- und Kontrollzählung**: Ein verwandtes Problem, das in Delphi häufig auftritt, ist die Verwirrung zwischen `ComponentCount` und `ControlCount`. Dies kann zu Missverständnissen führen, wenn versucht wird, die Anzahl der Komponenten oder Steuerelemente in einem Container zu zählen[2].

Um diese Probleme zu umgehen, können folgende Ansätze hilfreich sein:

- **Verwendung von `TRegEx`**: Stellen Sie sicher, dass Sie die `TRegEx`-Klasse korrekt verwenden und die Gruppen richtig referenzieren. Prüfen Sie, ob die Gruppen tatsächlich vorhanden sind, bevor Sie auf sie zugreifen.
- **Prüfen der PCRE-Version**: Überprüfen Sie, welche Version von PCRE Ihre Delphi-Version verwendet und ob es möglich ist, auf eine neuere Version zu aktualisieren, die native UTF-16-Unterstützung bietet.
- **Debugging und Tests**: Führen Sie umfangreiche Tests durch, um sicherzustellen, dass die regulären Ausdrücke wie erwartet funktionieren, und verwenden Sie Debugging-Tools, um Probleme zu identifizieren.

Hier ist ein Beispiel, wie Sie sicherstellen können, dass die Gruppen korrekt gezählt und referenziert werden:

```

Delphi-Quellcode:
uses
  System.RegularExpressions, System.SysUtils;

var
  text: string;
  pattern: string;
  matches: TMatchCollection;
  match: TMatch;
  mainToken, subTokens: string;
begin
  text := 'ABSCHNITT 14: Angaben zum Transport'#13#10 +
          '14.1 UN-Nummer'#13#10 +
          'ADR/RID: 2735 IMDG: 2735 IATA: 2735'#13#10 +
          '14.2 Ordnungsgemäße UN-Versandbezeichnung'#13#10 +
          'ADR/RID: AMINE, FLÜSSIG, ÄTZEND, N.A.G. (3-Aminopropyltriethoxysilan) IMDG: AMINES, LIQUID, CORROSIVE, N.O.S. (Triethoxy(3-aminopropyl)silane) IATA: Amines, liquid, corrosive, n.o.s. (Triethoxy(3-aminopropyl)silane)'#13#10 +
          '14.3 Transportgefahrenklassen ADR/RID: 6.1 (3, 8)'#13#10 +
          '14.4 Verpackungsgruppe ADR/RID: II'#13#10 +
          '14.5 Umweltgefahren ADR/RID: nein'#13#10 +
          'IMDG: 8'#13#10 +
          'IMDG: II'#13#10 +
          'IMDG Meeresschadstoff: nein'#13#10 +
          'IATA: 8'#13#10 +
          'IATA: II';

  pattern := '(1|2|3|4\.1|4\.2|4\.3|5\.1|5\.2|6\.1|6\.2|7|8|9)(?:\s*\((1|2|3|4\.1|4\.2|4\.3|5\.1|5\.2|6\.1|6\.2|7|8|9(?:,\s*(1|2|3|4\.1|4\.2|4\.3|5\.1|5\.2|6\.1|6\.2|7|8|9))*)\))?';

  matches := TRegEx.Matches(text, pattern);

  if matches.Count > 0 then
  begin
    for match in matches do
    begin
      mainToken := match.Groups[1].Value;
      if match.Groups.Count > 2 then
        subTokens := match.Groups[2].Value
      else
        subTokens := '';
        
      if subTokens <> 'then
        WriteLn('Gefundener Ausdruck: ', mainToken, ' (', subTokens, ')')
      else
        WriteLn('Gefundener Ausdruck: ', mainToken, ' ()');
    end;
  end
  else
  begin
    WriteLn('Gefundener Ausdruck: ');
  end;
end.
Dieser Code stellt sicher, dass die Gruppen korrekt erfasst und ausgegeben werden, und zeigt leere Strings an, wenn keine Gruppen vorhanden sind.

Citations:
[1] https://www.delphipraxis.net/213258-...-debuggen.html
[2] https://stackoverflow.com/questions/...pbox-returns-0
[3] https://www.regular-expressions.info/delphi.html
[4] https://en.delphipraxis.net/topic/85...erent-columns/

Kann mir jemand sagen wie ich das Problem löse? Ich habe 10.1 BERLIN RAD
DANKE
  Mit Zitat antworten Zitat
shebang

Registriert seit: 7. Feb 2020
116 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: REGEX mit TMatchCollection

  Alt 25. Jul 2024, 11:27
Delphi-Quellcode:
if matches.Count > 0 then
  begin
    if match.Groups.Count>1 then
Die Counts der Gruppen sind immer 0!
Das liegt daran, dass du hier auf match statt auf matches zugreifst.
  Mit Zitat antworten Zitat
peterbelow

Registriert seit: 12. Jan 2019
Ort: Hessen
688 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: REGEX mit TMatchCollection

  Alt 25. Jul 2024, 11:35
Es würde helfen, wenn Du uns auch sagen würdest, was Du in den einzelnen Gruppen als Resultat erwartest. Eine komplexe regex korrekt zu formulieren ist schwierig und sehr fehleranfällig. Ich würde den Text mittels einer TStringlist erstmal in Zeilen zerlegen und dann die Zeilen nacheinander analysieren.
Peter Below
  Mit Zitat antworten Zitat
wschrabi

Registriert seit: 16. Jan 2005
442 Beiträge
 
#4

AW: REGEX mit TMatchCollection

  Alt 25. Jul 2024, 12:42
Delphi-Quellcode:
if matches.Count > 0 then
  begin
    if match.Groups.Count>1 then
Die Counts der Gruppen sind immer 0!
Das liegt daran, dass du hier auf match statt auf matches zugreifst.
Nein, wenn ich matches.Groups.Count mache kommt ein Compiler Fehler. (siehe BILD)
ABer etwas stimmt, ich muss die IF in die loop reintun.

EIN TREFFER wäre lt. der REGEX: 6.1 (3, 8)
im TEXT die Zeile 14.3
Die Regex müßte aber passen, doch wieso ist Groups immer 0. Was hat es mit den Bug - wie berichtet auf sich?
Besten DANK
Miniaturansicht angehängter Grafiken
bug_delphi_matches.jpg  
  Mit Zitat antworten Zitat
shebang

Registriert seit: 7. Feb 2020
116 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: REGEX mit TMatchCollection

  Alt 25. Jul 2024, 13:41
Du kannst das Ganze etwas vereinfachen, deine for-Schleife fängt den Fall, dass es keine Matches gibt schon ab:
Delphi-Quellcode:
for match in matches do begin
  if match.Groups.Count < 3 then Continue;

  mainToken := match.Groups[1].Value;
  subTokens := match.Groups[2].Value;
  if subTokens <> 'then
    Result:= mainToken+' ('+ subTokens+ ')'
  else
    Result:= mainToken;
end;
Deine RegEx enthält aber nur eine Capturing Group und eine Non-capturing Group, es wird also nie mehr als 2 Groups geben können.
Beschreibe doch bitte mal, was deine RegEx eigentlich erreichen soll.

Geändert von shebang (25. Jul 2024 um 13:45 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:25 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz