Delphi-PRAXiS
Seite 3 von 4     123 4      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Regex Erläuterungen (https://www.delphipraxis.net/216333-regex-erlaeuterungen.html)

Stolle58 15. Dez 2024 08:25

AW: Regex Erläuterungen
 
"WZ 123456" oder "12.123.45678" sind dann Falsch, wenn Leerzeichen und Punkt ungültige Zeichen sind.

sko1 15. Dez 2024 09:36

AW: Regex Erläuterungen
 
Dann brauche ich einen anderen Ansatz, um auch bei komplexen Vorgaben unerlaubte Zeichen zu finden:

Aus der Hilfe:
Matches gibt alle Übereinstimmungen zurück, die im Input-String als eine TMatchCollection-Instanz vorhanden sind

Also wollte ich mit der originalen Regex eine MatchCollection haben und deren Länge auswerten:
Delphi-Quellcode:
var
  res: TMatchcollection;
begin
  // Pattern ist '^[a-zA-Z0-9$%&;\*\+\-/]{1,36}$'
  res := TRegEx.Matches(AttributInhalt, pattern);
  if res.count <> Length(Attributinhalt) then
   ...
  begin
res.count aber ist immer = 0
Irgendwas mache ich immer noch falsch :-(

Ciao
Stefan

shebang 15. Dez 2024 10:01

AW: Regex Erläuterungen
 
Irgendwie drehen wir uns aktuell etwas im Kreis.

Dein Pattern überprüft, ob dein Input exakt der Vorgabe entspricht. Wenn das nicht der Fall ist, dann ist das Ergebnis natürlich leer. Das "^" und "$" am Anfang und Ende des Pattern steht für den Anfang und das Ende deines Inputs.

Wenn du die jedes Zeichen einzeln prüfen willst, dann könntest du das Pattern "[a-zA-Z0-9$%&;\*\+\-\/]" verwenden.

sko1 15. Dez 2024 10:10

AW: Regex Erläuterungen
 
Du hast schon Recht, ich dreh mich im Keis...
Ich muss doch nur unerlaubte Zeichen in einem String finden die nicht der vorgegebenen Expression entsprechen...

Bei dem einfachen Beispiel kann ich die Expression ja negieren, wie aber bei solchen Konstrukten wie
'^([A-Z]{4}[A-Z]{2}([A-Z0-9]){2}([A-Z0-9]){0,3})$'

Ich hatte nun die Idee den zu untersuchenden Inhalt zeichenweise per Match zu testen bis keine Übereinstimmung mehr vorliegt
also
Zeichen 1 prüfen
Zeichen 1..2 prüfen
Zeichen 1..3 prüfen
Zeichen 1..4 prüfen
usw.
aber auch da schlägt die Längenprüfung zu

Deshalb der Ansatz per Matches in der Hoffnung, dass da aller erlaubten Zeichen enthalten sind (also ohne den Pattern zu negieren) nur funktioniert das so leider nicht!

Es muss dafür doch irgendeine Lösung geben!

Ciao
Stefan

shebang 15. Dez 2024 13:32

AW: Regex Erläuterungen
 
Zitat:

Zitat von sko1 (Beitrag 1544230)
Es muss dafür doch irgendeine Lösung geben!

Ok, dann gib uns bitte nochmal ein ganz konkretes Beispiel für einen Input und was exakt du dann als Output von Matches haben möchtest.

Stolle58 16. Dez 2024 10:16

AW: Regex Erläuterungen
 
[QUOTE=sko1;1544226]D
Delphi-Quellcode:
var
  res: TMatchcollection;
begin
  // Pattern ist '^[a-zA-Z0-9$%&;\*\+\-/]{1,36}$'
  res := TRegEx.Matches(AttributInhalt, pattern);
  if res.count <> Length(Attributinhalt) then
   ...
  begin
Wie ist AttributInhalt deklariert?

Mit dem Pattern '^[a-zA-Z0-9$%&;\*\+\-/]{1,36}$' kannst du nur eine Zeile prüfen.
Für einen größeren Text ist das Pattern Ungeeignet.

z.B.:
Code:
'WZ123456'
'1211234542' // Ergebnis Pattern gefunden res = 2
'WZ123456 1211234542' // Ergebnis Pattern nicht gefunden res = 0
PS.
Pattern - '^[a-zA-Z0-9$%&;\*\+\-/]{1,36}$'
sollte '^[a-zA-Z0-9$%&;\*\+\-\/]{1,36}$' so aussehen.
Beim letzte Slash muß ein Backslsh vorran gestellt werden.

Stolle58 16. Dez 2024 10:27

AW: Regex Erläuterungen
 
[QUOTE=sko1;1544226]D
Delphi-Quellcode:
var
  res: TMatchcollection;
begin
  // Pattern ist '^[a-zA-Z0-9$%&;\*\+\-/]{1,36}$'
  res := TRegEx.Matches(AttributInhalt, pattern);
  if res.count <> Length(Attributinhalt) then
   ...
  begin
Wie ist AttributInhalt deklariert?

Mit dem Pattern '^[a-zA-Z0-9$%&;\*\+\-/]{1,36}$' kannst du nur eine Zeile prüfen.
Für einen größeren Text ist das Pattern Ungeeignet.

z.B.:
Code:
'WZ123456'
'1211234542' // Ergebnis Pattern gefunden res = 2

'WZ123456 1211234542' // Ergebnis Pattern nicht gefunden res = 0

sko1 19. Dez 2024 07:53

AW: Regex Erläuterungen
 
Hallo,

nach Tagen vergeblicher Versuche frage ich hoch mal anhand eines ganz konkreten Beispiels:

Pattern = '^([A-Z]{2}\d\d([A-Za-z0-9]){11,30})$'
Ich interpretiere das so;
2 Zeichen A...Z
2 Ziffern
11-36 Zeichen A...Za...z0...9

Damit sollte 'AA11abcdefghijkl' gültig sein?
Als Input kommt aber z.B. 'AA11abcdefghij' dann sind alle Zeichen gültig, aber der letzte Teil zu kurz
Als Input kommt aber z.B. 'Ax11abcdefghijkl' dann ist das zweite Zeichen falsch
Wie macht man nun dem Anwender ersichtlich, wo er Eingabefehler hat?

Ciao
Stefan

Rollo62 19. Dez 2024 08:18

AW: Regex Erläuterungen
 
Du könntest nach einem fehlgeschlagenem RegEx noch die Abschnitte einzeln prüfen.
In etwa so (ungetestet):

Delphi-Quellcode:
function ValidateInputByPosition(Input: string): string;
var
  Match: TMatch;
  Errors: TStringList;
  LengthPart: Integer;
begin
  Errors := TStringList.Create;
  try
    // Vollständige Musterprüfung
    if not TRegEx.IsMatch(Input, '^([A-Z]{2}\d{2}[A-Za-z0-9]{11,30})$') then
    begin
      // Abschnitt 1: Zwei Großbuchstaben
      if not TRegEx.IsMatch(Input, '^[A-Z]{2}') then
        Errors.Add('Die Eingabe muss mit zwei Großbuchstaben beginnen (z. B. ''AA'').');
     
      // Abschnitt 2: Zwei Ziffern
      if not TRegEx.IsMatch(Input, '^[A-Z]{2}\d{2}') then
        Errors.Add('Nach den Großbuchstaben müssen zwei Ziffern folgen (z. B. ''11'').');
     
      // Abschnitt 3: Länge des letzten Teils
      LengthPart := Length(Copy(Input, 5, MaxInt));
      if LengthPart < 11 then
        Errors.Add(Format('Der letzte Teil muss mindestens 11 Zeichen lang sein, aber es sind nur %d Zeichen.', [LengthPart]))
      else if LengthPart > 30 then
        Errors.Add(Format('Der letzte Teil darf maximal 30 Zeichen lang sein, aber es sind %d Zeichen.', [LengthPart]));
    end;

    // Rückgabe
    if Errors.Count = 0 then
      Result := 'Die Eingabe ist gültig.'
    else
      Result := Errors.Text;
  finally
    Errors.Free;
  end;
end;

// Testaufruf
procedure TestValidationByPosition;
var
  Inputs: array[0..3] of string = ('AA11abcdefghijkl', 'AA11abcdefghij', 'Ax11abcdefghijkl', 'AA11abcdefghijklmnopqrstu');
  I: Integer;
begin
  for I := Low(Inputs) to High(Inputs) do
    Writeln(Format('Eingabe: %s', [Inputs[I]]), #13#10, ValidateInputByPosition(Inputs[I]));
end;

sko1 19. Dez 2024 08:30

AW: Regex Erläuterungen
 
Danke für das Beispiel!

Ich habe allerdings ca. 20 verschiedene Patterns (DATEV Vorgaben) und wenn ich so wie in Deinem Beispiel vorgehe müsste ich für jedes einzelne dann so etwas zusammenbasteln...

Gibt es da nicht irgendwas "allgemen verwndbares"?

Delphi-Quellcode:
      // Abschnitt 1: Zwei Großbuchstaben
      if not TRegEx.IsMatch(Input, '^[A-Z]{2}') then
        Errors.Add('Die Eingabe muss mit zwei Großbuchstaben beginnen (z. B. ''AA'').');
Wenn Input länger als die ersten beiden Zeichen ist, wird IsMatch da schon Fehler werfen weil es mehr als 2 Zeichen für '^[A-Z]{2}' sind , oder?

Ciao
Stefan


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:16 Uhr.
Seite 3 von 4     123 4      

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