Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Allgemeines Replace mit zwei Masken (https://www.delphipraxis.net/59703-allgemeines-replace-mit-zwei-masken.html)

glkgereon 27. Dez 2005 15:35


Allgemeines Replace mit zwei Masken
 
Hallo,

Ich suche im Moment einer Ersetzen-Funktion, der ich einen String und zwei Masken übergebe und die daraus einen neuen String "bastelt". Der erste String soll nach der ersten Maske analysiert werden und dann entsprechend in die zweite eingesetzt werden.

Beispiel:

String: 'DP ist toll'
Maske1: '%Forum% ist %Bewertung%'
Maske2: 'Der User findet %Forum% %Bewertung%'

heraus käme dann 'Der User findet DP toll'

gibt es sowas?

SirThornberry 27. Dez 2005 15:47

Re: Allgemeines Replace mit zwei Masken
 
warum lässt du nicht einfach 2 mal stringreplace drüber laufen?
Für Maske 1 wäre das ganze noch machbar aber für maske 2 ist das ganze unmöglich. Denn bei Maske 1 findet man das wort "ist" und kann aus deinem String das wort davor und danach nehmen. Aber für die Maske2 gibt es keine übereinstimmung woraus ersichtlich wäre welcher teil für "%Forum%" und welcher Teil für "%Bewertung%" steht. Das können nur inteligente Wesen wissen die auch wissen das DP ein forum ist und toll eine Bewertung.

glkgereon 27. Dez 2005 15:52

Re: Allgemeines Replace mit zwei Masken
 
nein, das ganze soll so gehen (Pseudocode):

Delphi-Quellcode:
function AdvReplace(Value,Mask1,Mask2: String):String;
var Vars: TVars;
begin
  Vars:=StoreVars(Value,Mask1);
  Result:=InsertVars(Vars,Mask2);
end;
also bei dem Beispiel
String: 'DP ist toll'
Maske1: '%Forum% ist %Bewertung%'
Maske2: 'Der User findet %Forum% %Bewertung%'

wäre dann

Vars:
%Forum% = DP
%Bewertung% = toll

und beim einsetzen wäre dann wieder %Forum% = DP und %Bewertung% = toll und der String 'Der User findet DP toll'

also die Maske1 soll auf den String angewendet werden, und diese Variablen rausgeholt werden, und in die zweite Maske eingesetzt werden.

Waldteufel 27. Dez 2005 15:59

Re: Allgemeines Replace mit zwei Masken
 
Hi Gereon.

Ich rate dir in diesem Fall zu regulären Ausdrücken. Ich habe momentan leider keine Unit zur Hand, aber ich weiß, dass es RegExp-Units für Delphi gibt.

Der Code würde dann etwa so aussehen.

Delphi-Quellcode:
function ForumsBewertung(s : string) : string;
var
  r : TRexExp;
begin
  r := TRegExp.Create('^(.*?) ist (.*?)$'); // Muster anlegen
  r.Match(s); // StoreVars()
  result := 'Der User findet ' + r.Matches[1] + ' ' + r.Matches[2] + '!'; // InsertVars()
  r.Free;
end;

{...}

var
  s1, s2 : string;
begin
  s1 := 'DP ist toll';
  s2 := ForumsBewertung(s1);
  ShowMessage(s2); // Zeigt 'Der User findet DP toll!' an
end.

glkgereon 27. Dez 2005 16:19

Re: Allgemeines Replace mit zwei Masken
 
Ich habe nun folgende Unit hier gefunden bei torry.

Aber was mache ich nun damit?

Khabarakh 27. Dez 2005 16:22

Re: Allgemeines Replace mit zwei Masken
 
Installieren und Waldteufels Code benutzen :wink: ?
Die richtige Webseite ist übrigens http://regexpstudio.com/TRegExpr/TRegExpr.html.

glkgereon 27. Dez 2005 16:42

Re: Allgemeines Replace mit zwei Masken
 
habs nun so:

Delphi-Quellcode:
var R: TRegExpr;
begin
  R:=TRegExpr.Create;
  R.Expression:='^(.*?) ist (.*?)$';
  R.InputString:=Edit1.Text;
  R.Compile;
  Edit2.Text := 'Der User findet ' + r.Match[1] + ' ' + r.Match[2] + '!';
  R.Free;
end;
Aber es kommt bei 'DP ist toll' immer 'Der User findet !' :(

Edit:
ausserdem möchte ich das einsetzen ja auch wieder dynamisch machen, das heisst mithilfe der zweiten Maske :(

Khabarakh 27. Dez 2005 17:36

Re: Allgemeines Replace mit zwei Masken
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hier ein Beispiel, nach Delphi musst du es aber allein übersetzen :wink: .
Code:
void TextBox1TextChanged(object sender, System.EventArgs e)
{
   string s = null;
   
   try {
      Regex regex = new Regex(textBox1.Text);
      Match match = regex.Match(textBox2.Text);
      s = textBox3.Text;
      foreach (string groupname in regex.GetGroupNames()) {
         s = s.Replace('%' + groupname + '%', match.Groups[groupname].Value);
      }
   }
   catch {
      s = null;
   }
   
   label1.Text = s;
}

glkgereon 27. Dez 2005 17:48

Re: Allgemeines Replace mit zwei Masken
 
es fängt ja schon damit an, das Create bei mir keine Parameter hat^^

Delphi-Quellcode:
procedure OnEditChange(Sender: TObject);
var S: String;
    R: TRegExpr;
begin
  try
    R:=TRegExpr.Create;
    R.Expression:=Edit1.Text;
    R.InputString:=Edit2.Text;
    S:=Edit3.Text;
   
//    foreach (string groupname in regex.GetGroupNames()) { 
//      S:=StringReplace(S,'%'+groupname+'%',match.Groups[groupname].Value,[rfReplaceAll]);
//    } 
  except
    S:='';
  end;
  Label1.Caption:=Ss;
end;
könnte vielleicht einer von euch mal seine RegExpr-Version anhängen?

glkgereon 27. Dez 2005 18:12

Re: Allgemeines Replace mit zwei Masken
 
Also...

Mein Fehler war, das ich das Exec vergessen hatte^^ funzt jetzt.

Nun habe ich noch folgende Funktion geschrieben, um eine Maske mit einfacher %Platzhalter% Syntax RegExpr-kopatibel zu machen und gleichzeitig (für den zweiten schritt, das einsetzen in die zweite Maske, eine Tabelle ID:Variable anzulegen)

Delphi-Quellcode:
  TData = record
    Name: String;
    ID: Integer;
  end;
  TDataTable = array of TData;

function Mask2RegExp(Mask: String; var Table: TDataTable):String;
var Akt, ID: Integer;
    S, R: String;
begin
  SetLength(Table,0);
  S:=Mask;
  Akt:=Pos('%',S);
  ID:=1;
  R:='';
  while Akt>0 do
    begin
    SetLength(Table,Length(Table)+1);
    Table[Length(Table)-1].ID:=ID;
    R:=R+Copy(S,1,Akt-1);
    Delete(S,1,Akt);
    Table[Length(Table)-1].Name:=Copy(S,1,Pos('%',S)-1);
    R:=R+'(.*?)';
    Delete(S,1,Pos('%',S));
    Akt:=Pos('%',S);
    Inc(ID);
    end;
  if R[1]='(' then R:='^'+R;
  R:=R+S;
  if Length(S)=0 then R:=R+'$';
  Result:=R+S;
end;
oder geht das auch einfacher?

Die Einsetzen-funktion sieht nun wie folgt aus:
Delphi-Quellcode:
function InsertIntoString(Mask: String; Table: TDataTable; R: TRegExpr):String;
var i:Integer;
    S: String;
begin
  S:=Mask;
  for i:=0 to Length(Table)-1 do
    S:=StringReplace(S,'%'+Table[i].Name+'%',R.Match[Table[i].ID],[rfReplaceAll]);
  Result:=S;
end;
So wird aus
Value: DP ist toll
Mask1: %wer% ist %wie%
Mask2: Angeblich ist %wer% %wie%
dann endlich: Angeblich ist DP toll

JUHUHUUUUU

ich bastel das noch schön in ne Klasse, und dann kommst in die CodeLib^^


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