Entwickler-Ecke

Sonstiges (Delphi) - Im String "mailto:" herausfiltern und ersetzen.


Steven - Di 24.06.03 18:45
Titel: Im String "mailto:" herausfiltern und ersetzen.
hallo ich muss folgenden string (kommt öfters vor)

Quelltext
1:
<a href="mailto:name@domain.de">name@domain.de</a>                    

aus einer html-datei herausfiltern weil ich diese austauschen muss.
das will mir mit dem code unter aber nicht ganz glücken, schwierigkeiten machen irgendwelche tags z.b. <br>usw.... die am ende dranhängen und die ich einfach nicht rausgefiltert kriege.
nein, ich will mir keinen spider bauen ;)

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
 for i := 0 to Memo4.Lines.Count - 1 do
      begin
        if Pos('<a href="mailto:', Memo4.Lines.Strings[i]) > 0 then
        begin
          s := '';
          for p := Pos('<a href="mailto:', Memo4.Lines.Strings[i]) to
            Length(Memo4.Lines.Strings[i]) do
            if Memo4.Lines.Strings[i][p] <> '</a>' then
              s := s + Memo4.Lines.Strings[i][p]
            else
              break;
         // while Pos(s[Length(s)], '..;!")]}?''><`´/' + '</br>' + '</p>' + '</a>' + ('a..z')) > 0 do
           // Delete(s, Length(s), 1);
          Memo5.lines.Add(s);
        end;
      end;
    end;


Moderiert von user profile iconTino: Titel geändert & Topic verschoben.


Delete - Di 24.06.03 20:11

Eventuell ist ja StringReplace was für dich.


Steven - Di 24.06.03 20:16

dachte ich auch schon...nur weiß ich aber nie so genau was nach dem letzten </a> kommt ...
hast du ne idee wie ich das machen könnte?
eigendlich müßte nach dem </a> ein neuer tag beginnen.
wenn ich alle html-tags replace, sind ja auch die tags weg die ich behalten will, hmm.


Delete - Di 24.06.03 20:20

Du willst doch nur die E-Mail-Adresse ersetzten. Laß doch die Tags in Ruhe die haben damit doch gar nichts am Hut.


Steven - Di 24.06.03 20:22

nein...das stimmt nicht ich muss dieses mailto auch austauschen, mein mailto setzt sich aus javascript zusammen, deshalb


Delete - Di 24.06.03 20:50

Steven hat folgendes geschrieben:
mein mailto setzt sich aus javascript zusammen, deshalb

Wie sieht das aus?


Steven - Di 24.06.03 20:56


Quelltext
1:
2:
3:
4:
<script language="javascript">
document.write("<a href=\"mailto:")
 document.write("info@web.de\">info@web.de<\/a>")
</script>

so siehts aus...


Tweafis - Di 24.06.03 20:58

Das kommt doch auf exact das gleiche raus ob du das machst oder direkt den <a>-Tag änderst...


Steven - Di 24.06.03 21:02

:think:
ich brauche ja nur das mailto:info@web.de zu replacen aber mir ist nicht ganz klar wie ich das machen kann weil nach dem
<a href="mailto;info@web.de">info@web.de</a>
ja wieder ein tag kommt und ich weiss auch nicht welche emailadressen vorkommen... wenn ich die emaiadresse weiß, dann funktioniert das ja so:

Delphi-Quelltext
1:
 Memo4.text:=Stringreplace(Memo4.text,'<a href="mailto;info@web.de">info@web.de</a>',''+neu.text+'',[rfReplaceAll]);                    


Delete - Di 24.06.03 21:14

Ist dass denn so schwer? :roll:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
var
  s : String;
begin
  s := Memo1.Text;
  s := StringReplace(s, 
    '<a href="mailto;info@web.de">info@web.de</a>',
    '<a href="mailto;foo@bar.de">foo@bar.de</a>,'
    [rfReplaceAll];
  Memo1.text := s;


Dann gehst du alt den Text so lange durch bis du alles hast:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
var
  s : String;
  i : Integer;
  sl : TStringList;
begin
  s := Memo1.Text;
  sl := TStringList.Create;
  // sl mit den neuen Adressen füllen
  try
    for i := 0 to sl.Count-1 do
      s := StringReplace(s, 
        '<a href="mailto;info@web.de">info@web.de</a>',
        sl.Strings[i],
        [rfReplaceAll];
  finally
    sl.Free;
  end;
    Memo1.Text := s;


Steven - Di 24.06.03 21:17

aber wenn ich die emailadreesen vorher doch nicht kenne!


Delete - Di 24.06.03 21:20

Aber wenn du sie ersetzen willst, muß du sie ja irgendwann kennen, sonst kannst du nichts ersetzen.


Steven - Di 24.06.03 21:23

schau dir bitte mein erstes posting in diesem thread an.
damit habe ich versucht die mailto's auszulesen (sozusagen "kennenzulernen")
und in der reihenfolge wie sie ausgelesen werden auch wieder zu ersetzen...
zumindestens war das mein ansatz


Delete - Di 24.06.03 21:42

Moment. Ich darf mal kurz gedanklich nachvollziehen, was du da vor hast.

Die Adressen stehen so im Text:

mpuff@luckie-online.de
foo@luckie-online.de
bar@luckie-online.de

In der Reihenfolge und noch mit dem ganzen HTML-Gedönse drumrum.

Jetzt extrahierst du sie aus dem Text und hast sie dann wegen mir in einer Stringliste stehen.

Und jetzt, und jetzt hapert es bei mir etwas, was du jetzt vor hast. Jetzt willst du eine dir bekannte E-Mail Adresse mit den extrahierten ersetzen? Was bedeutet "in dieser Reihenfolge"?


Steven - Di 24.06.03 21:54

Zitat:
Jetzt extrahierst du sie aus dem Text und hast sie dann wegen mir in einer Stringliste stehen.

genau das ist der punkt an dem ich nicht weiter komme.
bei mir hängen immer noch irgendwelche tags oder so'n müll dran.


Zitat:
Jetzt willst du eine dir bekannte E-Mail Adresse mit den extrahierten ersetzen? Was bedeutet "in dieser Reihenfolge"?


1 mpuff@luckie-online.de
2 foo@luckie-online.de
3 bar@luckie-online.de

ja, sollen halt wieder an der gleichen stelle stehen, nicht vertauscht ...
eigendlich soll alles so bleiben wie es ist, nur das

Quelltext
1:
<a href="mailto:mpuff@luckie-online.de ">mpuff@luckie-online.de </a>                    

soll durch:

Quelltext
1:
2:
3:
4:
<script language="javascript"> 
document.write("<a href=\"mailto:") 
document.write("mpuff@luckie-online.de \">mpuff@luckie-online.de <\/a>") 
</script>
ersetzt werden...


Delete - Di 24.06.03 21:58

Dann mach es doch so:

alter String: <a href="mailto:mpuff@luckie-online.de ">mpuff@luckie-online.de </a>

neuer String: <script language="javascript">
document.write("<a href=\"mailto:")
document.write("mpuff@luckie-online.de \">mpuff@luckie-online.de <\/a>")
</script>

Und das ganze mit StringReplace.


Steven - Di 24.06.03 22:03

ok...ist klar
damit ist aber nicht meine frage beantwortet, was wenn es verschiedene emailadressen sind?
drücke ich mich so undeutlich aus....? :autsch:


Delete - Mi 25.06.03 00:33


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
procedure GetEMails(s: String; sl: TStrings);
var
  MailAddy: String;
  p: PChar;
  Start: PChar;
begin
  p := PChar(s);
  while p^ <> #0 do
  begin
    { '@' gefunden }
    if p^ = #64 then
    begin
      { zurückgehen bis ein Leerzeichen oder Zeilenumbruch kommt }
      while (p^ <> #32and (p^ <> #13and (p^ <> #10do
        Dec(p);
      { Anfang gefunden -> merken }
      Start := p+1;
      { eine Schritt nach vorne gehen, sonst hängen wir }
      p := p+1;
      { wieder nach vorne gehen bis zum nächsten Leerzeichen }
      while (p^ <> #32do
        Inc(p);
      { gefunden }
      SetString(MailAddy, Start, p-Start);
      sl.Add(MailAddy);
    end;
    Inc(p);
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  GetEMails(Memo1.Text, Listbox1.Items);
end;

Probier es mal damit. Das holt dir alle E-Mail Adresse aus einem Text raus. Du mußt es nur etwas anpassen. Wenn ein @ gefunden wurde mußt du nicht bis zum ersten Leerzeichen zurückgehen, sondern bis zum nächsten ":". Und dann auch wieder nicht bis zum nächsten Leerzeichen nach vorne gehen, sondern bis zum nächsten " " ".
Über geben kannst du alternativ zu Listbox1.Items auch eine Stringliste.

So, ich hoffe jetzt konnte ich dir helfen. :?


Steven - Mi 25.06.03 07:59

vielen dank für deine bemühungen mir helfen zu wollen,
leider kommt nun doch ein "ABER"...
dein code macht die gleichen "fehler" wie mein erster.
was wenn keine leerzeichen da sind? :idea:


Delete - Mi 25.06.03 08:31

Steven hat folgendes geschrieben:
dein code macht die gleichen "fehler" wie mein erster.

Und funktioniert auch nicht bei Email-Adressen wie dieser hier:

Quelltext
1:
2:
3:
<a href="mailto:mpuff%40 ...">
Michael
</a>

:)

@Steven: Du solltest dir diesen [http://www.delphi-forum.de/viewtopic.php?t=13076] Beitrag vielleicht mal ansehen.


Steven - Mi 25.06.03 09:13

darum geht es doch überhaupt nicht, und hat mit meiner frage nichts zu tun...


Delete - Mi 25.06.03 09:31

Ach nein?

Du hast offensichtlich eine HTML-Seite, aus der du die Email-Adressen herausfiltern willst. Du könntest das natürlich mit deinem Memo machen, aber das setzt voraus, dass du die Syntax der HTML-Seite beachten musst. Umsonst hast du ja wohl nicht geschrieben:
Steven hat folgendes geschrieben:
was wenn keine leerzeichen da sind?


Bei dem Parser (sprich: TWebBrowser, in dem Fall) interessiert das nicht, weil du dort mit einer einfachen for-Schleife Zugriff auf alle Links des Dokumentes hast. Unabhängig davon, wie der HTML-Quelltext aussieht; ob mit Leerzeichen, ohne, mit Zeilenumbruch, alles in einer Zeile ... was auch immer ...

Ich persönlich halte das für einfacher als das Rumgesuche in einem Memo, aber es war auch nur ein Tipp.


Steven - Mi 25.06.03 09:38

da leuchtet mir ein, das mit dem memo ist auch mein erster versuch und keine lösung, deshalb meine fragen... das man das besser machen kann ist mir klar.


Delete - Mi 25.06.03 09:59

Dann probier´s mit dem WebBrowser doch einfach mal aus. Du wirst sehen, dass es sehr leicht ist. ... Aber immer erst meckern ... :wink:


Steven - Mi 25.06.03 11:29

ich hab doch nicht gemeckert :beer:

ich hab mal sowas ausprobiert, funktioniert nicht...
weißt du warum?

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
 function GetMailto(WebDoc: iHTMLDocument2): string;
var
  re: integer;
  HTMLel: iHTMLElement;
  HTMLcol: iHTMLElementCollection;
  HTMLlen: Integer;
begin
  Result := '';
  if Assigned(WebDoc) then
  begin
    HTMLcol := WebDoc.Get_all;
    HTMLlen := HTMLcol.Length;
    for re := 0 to HTMLlen - 1 do
    begin
      HTMLel := HTMLcol.Item(re, 0as iHTMLElement;
      if HTMLEl.tagName = 'mailto:' then
        Result := Result + HTMLEl.innerHTML;
    end;
  end;
end;


Delete - Mi 25.06.03 11:57

Auf die Schnelle:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
function GetMailto(WebDoc: iHTMLDocument2): string;
var
  re    : integer;
  aLink : IHTMLElement;
begin
  Result := '';

  if Assigned(WebDoc) then begin
    for re  := 0 to WebDoc.links.length - 1 do begin
      aLink := WebDoc.links.Item(re,0as IHTMLElement;

      if(pos('mailto:',aLink.getAttribute('href',0)) > 0then
        Result := Result +
          aLink.toString + '(' + aLink.innerHTML + ')' +
          #13#10;
    end;
  end;
end;

Du könntest auch

Delphi-Quelltext
1:
      if(pos('mailto:',aLink.toString) > 0then                    

benutzen, weil "toString" ja nur den eigentlichen Link in einen (Wide)String konvertiert. - Ich weiß nicht, ob du den Linktext auch noch brauchst. Ich habe ihn spaßeshalber mal in Klammern angehangen (s. "innerHTML"). Wenn du evtl. HTML-Tags nicht sehen willst, etwa die Fett-Markierung hier

Quelltext
1:
<a href="mailto:foo@man.chu"><b>Foo</b> im Internet</a>                    

dann nimm statt "innerHTML" eben "innerText".


Delete - Mi 25.06.03 12:11

Ach so, um deine Frage noch fix zu beantworten -

Die Prüfung

Delphi-Quelltext
1:
if HTMLEl.tagName = 'mailto:' then                    

muss fehlschlagen, weil "mailto:" ja kein Tagname sondern nur der Teil eines Attributes (von href nämlich!) ist. Du solltest also auf den Tagnamen "a" prüfen (weil <a href="...">Text</a>) und dabei beachten, dass (zumindest bei mir) die Namen grundsätzlich in Großbuchstaben zurückgeliefert werden .. warum auch immer ...

Deine Idee bringt so Erfolge:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
  if Assigned(WebDoc) then begin
    HTMLcol  := WebDoc.Get_all;
    for re   := 0 to HTMLCol.length - 1 do begin
      HTMLel := HTMLCol.Item(re,0as IHTMLElement;

      if(lowercase(HTMLel.tagName) = 'a'and
        (pos('mailto:',HTMLel.toString) > 0then
      Result := Result + HTMLel.toString + #13#10;
    end;
  end;


Steven - Mi 25.06.03 13:20

deins funktioniert richtig gut, super :dunce: