Einzelnen Beitrag anzeigen

wschrabi

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

REGEX mit TMatchCollection

  Alt 25. Jul 2024, 11: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