Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Funktion zum Finden eines Wildcard-Strings (https://www.delphipraxis.net/99385-funktion-zum-finden-eines-wildcard-strings.html)

SMALLID 11. Sep 2007 14:06


Funktion zum Finden eines Wildcard-Strings
 
Ich möchte in einer Textdatei (zur Vereinfachung: in einem String) das Vorkommen (den Index) eines anderen Strings, den ich als Maske angebe, bekommen. Geht das bereits in Delphi? Mit TMask hatte ich leider keinen Erfolg, dar mir "Matches" nur einen boolean zurückgibt und ich ja den integer, oder noch besser, eine liste von integern brauche.

Ideal also frage ich:

IndexOf('###*###', myString) und er gibt mir bspw. die Positionen von '###NAME###' und '###TITEL###' in "myString" zurück.

shmia 11. Sep 2007 16:44

Re: Funktion zum Finden eines Wildcard-Strings
 
Wenn du Wildcards mit einem String vergleichst, könnte ja im Extremfall eine Unmenge von Treffern
entstehen.
Wildcard = '1*1' String = '111111111111111181111';
Deshalb gibt die Funktion nur die Information: Wildcard passt auf den String oder eben nicht
Kannst du deine Suche vielleicht auf einen Treffer pro Zeile (in der Datei) beschränken ?

SMALLID 11. Sep 2007 16:47

Re: Funktion zum Finden eines Wildcard-Strings
 
Im Prinzip ist mein Problem nur, Marker in einer Art Template-Email zu finden und mit Kundendaten zu ersetzen, um so die Anrede neu zu generieren ("Serienmail", wenn man so will). Das Problem ist aber so generell, dass ich da eigentlich ne elegante, bereits existierende Lösung vermutet hätte.

Zur Info für andere: Habe hier was gefunden, was mir gleich die Strings in einem Array gibt und mir in diesem Fall noch besser hilft. Es kann sich ja trotzdem mal wer Gedanken um das Index Problem machen. Hatte eigentlich gedacht, dass es - zumindest in der Klasse Masks - schon sowas gibt.

shmia 11. Sep 2007 17:03

Re: Funktion zum Finden eines Wildcard-Strings
 
Zitat:

Zitat von SMALLID
Im Prinzip ist mein Problem nur, Marker in einer Art Template-Email zu finden und mit Kundendaten zu ersetzen, um so die Anrede neu zu generieren ("Serienmail", wenn man so will). Das Problem ist aber so generell, dass ich da eigentlich ne elegante, bereits existierende Lösung vermutet hätte.

Achso, da hätte ich dir eine Idee/Lösung.
Ich würde die Variablen z.B. in zwei $-Zeichen einschliesen.
Das EMail-Template könnte dann so aussehen:
Code:
$GRUSSFORMEL$

Betreff: Ihre Bestellung vom $ORDERDATE$
Kundennumer: $CUSTOMERNO$

...
$DISCLAIMER$
Dann brauchst du nur noch die Variablennamen durch echten Text ersetzen:
Delphi-Quellcode:
s := template;
s := StringReplace(s, '$GRUSSFORMEL$', grussformel);
s := StringReplace(s, '$CUSTOMERNO$', kundennummer);
Wenn dir das zu starr ist, dann solltest du das Template Zeichen für Zeichen durchgehen.
Wenn es ein $-Zeichen ist, dann Position merken und weitersuchen bis zum nächsten $-Zeichen.
Nun hast du 2 Positionen und kennst den Text dazwischen.
Jetzt wird eine Callback-Methode aufgerufen (Input: Text zwischen den $-Zeichen, Output: Ersetzungstext)

marabu 11. Sep 2007 17:39

Re: Funktion zum Finden eines Wildcard-Strings
 
Hallo,

wenn der Marker noch frei gewählt werden kann, dann existiert zumindest in meiner Delphi-Version die Komponente TPageProducer, die genau das gewünschte macht: Ereignisgesteuerte Verarbeitung eines Templates - sehr komfortabel und auch für komplexere Aufgaben geeignet, da mehrere dieser Komponenten beliebig verknüpft werden können.

Grüße vom marabu

SMALLID 11. Sep 2007 17:46

Re: Funktion zum Finden eines Wildcard-Strings
 
Verzeihung ich hab' mich da in der letzten Nachricht wohl zu knapp ausgedruckt. Das konkrete Problem ist ein Teilproblem und besteht eigentlich darin, dass ich die vorhandenen Marker (deren Namen ich nicht kenne und die extern selbst bestimmt werden können) ersteinmal in einer Liste anzeigen möchte und ihnen über diese Liste dann Feldnamen aus der Datenbank zuordnen möchte. Ich muss die Marker also irgendwie auslesen. Einzige Konvention ist, dass ein Marker in "###"s gefasst werden muss, d.h. z.B. "###NAME###" oder "###EMAIL###". Das Programm soll dann danach über Wildcards (###*###) suchen und mir in der Liste der vorhandenen Marker dann "NAME" und "EMAIL" anzeigen.

Namenloser 11. Sep 2007 18:02

Re: Funktion zum Finden eines Wildcard-Strings
 
Hi,

ich fürchte, da gibt es ein Problem.

Bei
Code:
###name###
...
###email###
...
###telnummer###
würde die Funktion mit Wildcards zwar folgende Ergebnisse liefern:
1. ###name###
2. ###email###
3. ###telnummer###

ABER AUCH:
1. ###name###...###email###...###telnummer###
2. ###name###...###email###
3. ###email###...###telnummer###

Denn auch dort sind die Bedingungen erfüllt.

SMALLID 11. Sep 2007 18:09

Re: Funktion zum Finden eines Wildcard-Strings
 
Hmmm *guter* Einwand! (sorry bin seit 5:30 am auf den Beinen, ich lauf heut ned mehr ganz rund). Ich probier das dann mal mit BEG_NAME_END und BEG_EMAIL_END ---> BEG_*_END

shmia 11. Sep 2007 18:18

Re: Funktion zum Finden eines Wildcard-Strings
 
Kannst du dich gedanklich von den Wildcards trennen?
(Siehe auch Posting vom Namenlozer)
Das was ich oben geschrieben habe gilt auch dann, wenn der Marker statt dem $-Zeichen ein String mit '###' ist; es wird nur etwas komplizierter.
Ich hab' da mal eine Klasse angefangen, weil ich selbst EMail-Templates brauchen könnte:
Delphi-Quellcode:
 TStringReplaceEvent = function(const name:string):string;
 TStringTemplate = class(TObject)
  private
    FDelimiter: string;
    procedure SetDelimiter(const Value: string);

  public
    procedure FindTokens(const s : string; list:TStrings);
    procedure ReplaceTokens(const s : string; event:TStringReplaceEvent);

    property Delimiter : string read FDelimiter write SetDelimiter;

  end;
...
procedure TStringTemplate.FindTokens(const s: string; list: TStrings);
var
   i : Integer;
   p1, l, sl : Integer;
begin
   Assert(Assigned(list));
   p1 := 0;
   l := length(FDelimiter);
   sl := Length(s);
   if l = 0 then
      raise Exception.Create('TStringTemplate: Delimiter ist leer');
   i := 1;
   while i <= sl do
   begin
      if Copy(s, i, l) = FDelimiter then
      begin
         if p1 = 0 then
         begin // öffnender Delimiter
            p1 := i + l; // Startpunkt merken
            Inc(i, l); // Delimiter überspringen
         end
         else
         begin // schliessender Delimiter
            list.Add(Copy(s, p1, i-p1));
            p1 := 0;
            Inc(i, l); // Delimiter überspringen
         end;
      end;
      Inc(i); // nächstes Zeichen
   end;
   if p1 <> 0 then
      raise Exception.Create('TStringTemplate: schliessender Delimiter fehlt');
end;

SMALLID 11. Sep 2007 19:22

Re: Funktion zum Finden eines Wildcard-Strings
 
Sehr sehr schön! Der Code funktioniert in leichter Abwandlung bei mir sehr gut. Ich teste das jetzt mal und poste hier später einige zusätzliche Routinen. Im Handumdrehen haben wir eine Template Komponente. :D


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:38 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