Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Prüfen ob Wörter in einem String vorkommen, Reihenfolge egal (https://www.delphipraxis.net/28345-pruefen-ob-woerter-einem-string-vorkommen-reihenfolge-egal.html)

Gambit 23. Aug 2004 15:55


Prüfen ob Wörter in einem String vorkommen, Reihenfolge egal
 
Hallo,

ich möchte prüfen ob alle Wörter eines Strings in einem anderen String vorkommen. Dabei soll es egal sein in welcher Reihenfolge die Wörter stehen.
Beispiel:

String1: Otto Harfe spielt gern
String2: Otto spielt gern Harfe am Wochenende

Bei der Prüfung o.g. Beispiels soll eine Prüfung true zurückgeben.
Kann man das recursiv lösen? Hat jemand eine Idee?

Gruß

Gambit

Snoop007 23. Aug 2004 16:10

Re: Prüfen ob Wörter in einem String vorkommen, Reihenfolge
 
die funktion pos durchsucht einen string nach einem gesuchent string
wurde der entsprechende zu suchende string gefunden, gibt die funktione einen wert grösser 0 zurück

Sharky 23. Aug 2004 16:11

Re: Prüfen ob Wörter in einem String vorkommen, Reihenfolge
 
Hai Gambit,

entscheidend ist die Frage: Woher weisst Du wo ein Wort endet? Sind die Wörter immer durch ein blank getrennt?
Wenn Ja: Verwende einfach eine TStringList und schaue Dir mal die Eigenschaften DelimitedText und Delimiter an.
Damit und einer einfachen Schleife und der Funktion Pos sollte das ganze leicht zu lösen sein.

lume96 23. Aug 2004 17:08

Re: Prüfen ob Wörter in einem String vorkommen, Reihenfolge
 
Im Deinem Fall würde ich bei der POS-funktion vorsichtig vorgehen, die findet nämlich auch Substrings.

Z.B.:
String1 = 'Die Woche'
string2 = 'Die Sonne wird dieses Wochenende nur selten zu sehen sein'

Wenn Du hier mit Pos() Wort für Wort vergleicht (gegeben, Du hast die Strings in die verschiedenen Worte zerlegt), wird Dir Pos() sagen, alles ok, denn Pos('Woche','Wochenende') ist 1, also gefunden. Ich würde jedes Wort, vor dem Vergleich, noch zusätzlich am Anfang und am Ende mit einem 'Delimiter' versehen, der sonst eher nicht vorkommt z.B. #9 (Tabulation) wort1 := #9+wort1+#9.

Vorsicht auch bei Gross- und Kleinschreibung : Woche <> woche
Unter Umständen 'n Uppercase() oder lowercase() um jedes Wort, wenn bei Dir 'Woche' = 'woche' sein soll.

MfG
Lutz

Gambit 23. Aug 2004 17:14

Re: Prüfen ob Wörter in einem String vorkommen, Reihenfolge
 
Habe folgendes im Swiss-Center gefunden, irgendwie funzt es aber nicht, wenn ich nur ein Wort im Edit-Feld eingebe gehts, gebe ich mehr als eins ein, zeigt die StringList gar nicht mehr. Vielleicht hat ja mal einer Lust, das auszuprobieren. Die Methode, die den Text aus dem Memo in Wörter zerlegt funzt auf jeden Fall scheinbar prima(habs noch nicht mit Umlauten probiert..)

Delphi-Quellcode:
procedure SplitTextIntoWords(const S: string; words: TstringList);
var
  startpos, endpos: Integer;
begin
  Assert(Assigned(words));
  words.Clear;
  startpos := 1;
  while startpos <= Length(S) do
  begin
    // skip non-letters
    while (startpos <= Length(S)) and not IsCharAlpha(S[startpos]) do
      Inc(startpos);
    if startpos <= Length(S) then
    begin
      // find next non-letter
      endpos := startpos + 1;
      while (endpos <= Length(S)) and IsCharAlpha(S[endpos]) do
        Inc(endpos);
      words.Add(Copy(S, startpos, endpos - startpos));
      startpos := endpos + 1;
    end; { If }
  end; { While } 
end; { SplitTextIntoWords } 

function StringMatchesMask(S, mask: string;
  case_sensitive: Boolean): Boolean;
var
  sIndex, maskIndex: Integer;
begin
  if not case_sensitive then
  begin
    S   := AnsiUpperCase(S);
    mask := AnsiUpperCase(mask);
  end; { If } 
  Result   := True; // blatant optimism
  sIndex   := 1;
  maskIndex := 1;
  while (sIndex <= Length(S)) and (maskIndex <= Length(mask)) do
  begin
    case mask[maskIndex] of
      '?':
        begin
          // matches any character
          Inc(sIndex);
          Inc(maskIndex);
        end; { case '?' } 
      '*':
        begin
          // matches 0 or more characters, so need to check for
          // next character in mask
          Inc(maskIndex);
          if maskIndex > Length(mask) then
            // * at end matches rest of string
            Exit
          else if mask[maskindex] in ['*', '?'] then
            raise Exception.Create('Invalid mask');
          // look for mask character in S
          while (sIndex <= Length(S)) and
            (S[sIndex] <> mask[maskIndex]) do
            Inc(sIndex);
          if sIndex > Length(S) then
          begin
            // character not found, no match
            Result := False;
            Exit;
          end;
          { If } 
        end; { Case '*' }
      else if S[sIndex] = mask[maskIndex] then
        begin
          Inc(sIndex);
          Inc(maskIndex);
        end { If } 
        else
          begin
            // no match
            Result := False;
            Exit;
          end;
    end; { Case } 
  end; { While }
  // if we have reached the end of both S and mask we have a complete
  // match, otherwise we only have a partial match
  if (sIndex <= Length(S)) or (maskIndex <= Length(mask)) then
    Result := False;
end; { stringMatchesMask }

procedure FindMatchingWords(const S, mask: string;
  case_sensitive: Boolean; matches: Tstrings);
var
  words: TstringList;
  i: Integer;
begin
  Assert(Assigned(matches));
  words := TstringList.Create;
  try
    SplitTextIntoWords(S, words);
    matches.Clear;
    for i := 0 to words.Count - 1 do
    begin
      if stringMatchesMask(words[i], mask, case_sensitive) then
        matches.Add(words[i]);
    end; { For } 
  finally
    words.Free;
  end;
end;


 The Form has one TMemo for the text to check, one TEdit for the mask,
 one TCheckbox (check = case sensitive), one TListbox for the results,
 one Tbutton
}

procedure TForm1.Button1Click(Sender: TObject);
begin
  FindMatchingWords(memo1.Text, edit1.Text, checkbox1.Checked, listbox1.Items);
end;
Gruß

Gambit

Snoop007 23. Aug 2004 17:45

Re: Prüfen ob Wörter in einem String vorkommen, Reihenfolge
 
ich hätte das eher so gemacht
string1 = "Das Gross - Fest"
string2 = "das Grosse Festival hat begonnen"

Code:
wiederhole das ganze solange bis startpos_1 = die länge von string1 hat
  du guckst, ist die position vom leerzeichen grösser als die länge des strings
  wenn ja
    merken wert in startpos_1 // ertsmal die länge des zu suchenden strings bestimmen
 
  du kopiertst vom anfang aus string1 bis startpos_1 den string ( funktion copy ) in rem_s
  merke länge von rem_s in rem_l
  // jetzt haben wird den sting, den wir suchen möchten

  merke das ergebnis von pos wenn rem_s und string2 eingegebenwurde in str_2_pos

  ist tr_2_pos > 0
  wenn ja
    // ein string der dem zu suchenden string ähnelt wurde gefunden
    kopiere von der postition tr_2_pos aus strnig2 bis zu einem leerzeichen oder bis zum ende
    merke diesen wert in rem_s2
    ist rem_s2 = rem1 // prüfen ob er auch gleich ist
    wenn ja
      ist der zu suende string gefunden
ich hoffe ich habe keinen denkfehler geamcht :mrgreen:

Sharky 23. Aug 2004 17:52

Re: Prüfen ob Wörter in einem String vorkommen, Reihenfolge
 
Hai Gambit,

mit den Schlüsselwörtern von mir hätte es eigentlich gehen sollen :stupid:
Hier mal mein Versuch:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  str1 : String;
  str2 : String;
  sl  : TStringList;
  ndx : Integer;
  okay : Boolean;
begin
  str1 := 'Otto Harfe spielt gern';
  str2 := 'Otto spielt gern Harfe am Wochenende';
  okay := False;
  sl := TStringList.Create;
  try
    sl.Delimiter := ' ';
    sl.DelimitedText := str1;
    for ndx := 0 to pred (sl.Count) do
    begin
      okay := Pos (sl.Strings[ndx],str2) > 0; // Wort ist vorhanden
      if not (okay) then
      begin
        break;
      end;
    end;
  finally
    FreeAndNil (sl);
  end;
  if (okay) then
  begin
    ShowMessage ('Alle Wörter gefunden');
  end
  else
  begin
    ShowMessage ('Nicht alle Wörter gefunden');
  end;
end;

lume96 23. Aug 2004 18:25

Re: Prüfen ob Wörter in einem String vorkommen, Reihenfolge
 
Zitat:

Zitat von Gambit
Habe folgendes im Swiss-Center gefunden, irgendwie funzt es aber nicht, wenn ich nur ein Wort im Edit-Feld eingebe gehts, gebe ich mehr als eins ein, zeigt die StringList gar nicht mehr.
Delphi-Quellcode:
procedure SplitTextIntoWords(const S: string; words: TstringList);
var
  startpos, endpos: Integer;
begin

...

procedure TForm1.Button1Click(Sender: TObject);
begin
  FindMatchingWords(memo1.Text, edit1.Text, checkbox1.Checked, listbox1.Items);
end;
Gruß

Gambit

Hab den Code zwar nur kurz überflogen, aber so wie ich's verstanden habe macht der folgendes :

Bei
Delphi-Quellcode:
FindMatchingWords(string1, string2, checkbox1.Checked, listbox1.Items);
durchsucht er die STRING1 nach Übereinstimmungen mit der STRING2 die eine Suchmaske enthält und gibt das Resultat in die Listbox1 aus.

Z.B.:

Delphi-Quellcode:
   FindMatchingWords('OTTO spielt LOTTO', '?TT?', false, listbox1.Items);
sollte Dir nur OTTO ausgeben, während
Delphi-Quellcode:
   FindMatchingWords('OTTO spielt LOTTO', '*TT?', false, listbox1.Items);
Dir OTTO und LOTTO augeben sollte.

Hier wird eine Sting mit meheren Wörtern (String1) nach einer Übereinstimmung mit einer Suchmaske überprüft.
Also nicht das, was Du suchst.

Allerdings findest Du 'ne Menge interessanter Funktion die Dir helfen könnten, wie z.B. SlitTextIntoWords.

MfG.
LUtz

Gambit 23. Aug 2004 18:30

Re: Prüfen ob Wörter in einem String vorkommen, Reihenfolge
 
Jepp, Danke!!

Ja, es geht, hat aber tatsächlich den von Lutz angesprochenen Nachteil, das z.B Woche auch in Wochenende gefunden wird...

In dem Swiss Beispiel passiert das nicht, dafür habe ich noch nicht rausgefunden, warum es nicht alle Wörter in der StringList aufführt werden...

Gruß

Gambit

Gambit 23. Aug 2004 18:35

Re: Prüfen ob Wörter in einem String vorkommen, Reihenfolge
 
Oh überschneidung...danke Lutz!
Die Methode SplittTextintoWords sollte man aber tatsächlich gebrauchen können...

Gam

lume96 23. Aug 2004 18:37

Re: Prüfen ob Wörter in einem String vorkommen, Reihenfolge
 
Sharkys Funktion sollte funktionieren, allerdings mit zwei Einschränkungen :
1) Als Delimiter zwichen zwei Wörtern setzt er ein Leerzeichen voraus, d.h. bei
str1 := 'Otto Harfe spielt gern.';
str2 := 'Otto spielt gern Harfe am Wochenende';
würde es nicht mehr klappen, denn das letzte Wort der str1 nach dem Split wäre "gern." (mit dem Punkt am Ende).

2) Durch den direkten Vergleich mit Pos() werden auch Substrings gefunden, d.h. bei
str1 := 'Ot Harfe spielt gern';
str2 := 'Otto spielt gern Harfe am Wochenende';
würde er sagen, is OK den 'Ot' ist in 'Otto' enthalten.

Zum splitten der Wörter würde ich eher die Formel aus Deinem Code vom Swiss-Center benutzen und beim Vergleich, wie schon oben geschrieben das Pos leicht verändern.

MfG.
Lutz

Sharky 23. Aug 2004 18:47

Re: Prüfen ob Wörter in einem String vorkommen, Reihenfolge
 
Zitat:

Zitat von lume96
...2) Durch den direkten Vergleich mit Pos() werden auch Substrings gefunden,...

Hai Lutz,
das ist durch den einsatz einer zweiten TStringList leich zu umgehen. Dann bleibt "nur noch" das Problem mit dem Delimiter ;-)

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  str1 : String;
  str2 : String;
  sl1   : TStringList;
  sl2   : TStringList;
  ndx : Integer;
  okay : Boolean;
begin
  str1 := 'Otto Harfe spielt gern';
  str2 := 'Otto spielt gern Harfe am Wochenende';
  okay := False;
  sl1 := TStringList.Create;
  sl2 := TStringList.Create;
  try
    sl1.Delimiter := ' ';
    sl1.DelimitedText := str1;
    sl2.Delimiter := ' ';
    sl2.DelimitedText := str2;
    for ndx := 0 to pred (sl1.Count) do
    begin
      okay := sl2.IndexOf(sl1.Strings[ndx]) > -1;
      if not (okay) then
      begin
        break;
      end;
    end;
  finally
    FreeAndNil (sl1);
    FreeAndNil (sl2);
  end;
  if (okay) then
  begin
    ShowMessage ('Alle Wörter gefunden');
  end
  else
  begin
    ShowMessage ('Nicht alle Wörter gefunden');
  end;
end;

Gambit 23. Aug 2004 19:55

Re: Prüfen ob Wörter in einem String vorkommen, Reihenfolge
 
Also ich habe jetzt festgestellt, dass das Auffinden von Teilstrings, also z.B Woche in Wochenende teilweise sogar notwendig ist. Da die Methode splitTextintoWords die einzelnen Worte ja in eine Stringlist schreibt, brauche ich dann doch nur noch in einer Schleife die einzelnen Wörter mittels Pos im zweiten String suchen oder seh ich das jetzt falsch?

Gruß

Gambit

lume96 23. Aug 2004 20:10

Re: Prüfen ob Wörter in einem String vorkommen, Reihenfolge
 
Zitat:

Zitat von Sharky
Hai Gambit,

mit den Schlüsselwörtern von mir hätte es eigentlich gehen sollen :stupid:
Hier mal mein Versuch:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  str1 : String;
  str2 : String;
  sl  : TStringList;
  ndx : Integer;
  okay : Boolean;
begin
  str1 := 'Otto Harfe spielt gern';
  str2 := 'Otto spielt gern Harfe am Wochenende';
  okay := False;
  sl := TStringList.Create;
  try
    sl.Delimiter := ' ';
    sl.DelimitedText := str1;
    for ndx := 0 to pred (sl.Count) do
    begin
      okay := Pos (sl.Strings[ndx],str2) > 0; // Wort ist vorhanden
      if not (okay) then
      begin
        break;
      end;
    end;
  finally
    FreeAndNil (sl);
  end;
  if (okay) then
  begin
    ShowMessage ('Alle Wörter gefunden');
  end
  else
  begin
    ShowMessage ('Nicht alle Wörter gefunden');
  end;
end;

Dann würd ich doch einfach Sharkys Code von oben benutzen (habs noch mal gequoted) und

folgende Stelle

Delphi-Quellcode:
  try
    sl.Delimiter := ' ';
    sl.DelimitedText := str1;
    for ndx := 0 to pred (sl.Count) do
    begin
wie folgt erstetzen
Delphi-Quellcode:
  try
    SplitTextIntoWords(DeineString,s1); // Aus dem Swiss-Center
//    sl.Delimiter := ' ';
//    sl.DelimitedText := str1;
    for ndx := 0 to pred (sl.Count) do
    begin
Hoffe, dass das so klappt.

MfG
Lutz

Gambit 23. Aug 2004 20:35

Re: Prüfen ob Wörter in einem String vorkommen, Reihenfolge
 
gute Idee, aber ich glaube den Swiss-Code kann ich doch nicht nehmen weil er nur Buchstaben berücksichtigt und Zahlen außen vor läßt. Mit der "Der Pate 2" hätte ich dann wiederum Probleme, du weißt ja, was ich meine Lutz...

Gambit

lume96 23. Aug 2004 20:52

Re: Prüfen ob Wörter in einem String vorkommen, Reihenfolge
 
Zitat:

Zitat von Gambit
gute Idee, aber ich glaube den Swiss-Code kann ich doch nicht nehmen weil er nur Buchstaben berücksichtigt und Zahlen außen vor läßt. Mit der "Der Pate 2" hätte ich dann wiederum Probleme, du weißt ja, was ich meine Lutz...

Gambit

Kein Problem, einfach die Funktion "IsCharAlpha(S[startpos])" durch eine Eigene ersetzen, z.B.:
Delphi-Quellcode:
Function IsCharAlpha2(const mychar : string) : boolean;
const
 alphachar = 'abcd....xyz123...90';
begin
 result := (Pos(lowercase(mychar),alphachar)>0);
end;
wobei 'alphachar' 'ne Stringkonstante ist, in der Du alle Buchstaben, Zahlen, usw... hintereinander auslistest, welche Du als Buchstabe interpretiert haben willst.

Kommen wir der Sache näher :?:
MfG
Lutz

Gambit 23. Aug 2004 21:02

Re: Prüfen ob Wörter in einem String vorkommen, Reihenfolge
 
Mir raucht langsam der Kopf, denn ich glaube nicht. Selbst wenn ich den String in einzelne Wörter zerlegen kann und das scheinen wir ja hinzukriegen, wüßte ich jetzt nicht mehr, wie ich daraus eine Select-Abfrage basteln sollte...ich sollte das Programmieren vielleicht nochmal von vorne anfangen...

Gruß

Gambit

Robert_G 23. Aug 2004 21:31

Re: Prüfen ob Wörter in einem String vorkommen, Reihenfolge
 
Liste der Anhänge anzeigen (Anzahl: 1)
Falls du ein wenig in .Net interessiert bist...

Ich habe gerade aus "Jux" das Ganze mal in C#2.0 gebastelt (die Beta gibt's kostenlos bei M$ ;) )
Es ist nicht wirklich "hübsch", war aber in 10 Minuten fertig. (mit "IntelliSense tippt man schneller als ein MaiKäfer husten kann :P)

Code:
#region Using directives

using System;
using System.Collections.Generic;
using System.Windows.Forms;

#endregion

namespace FindMatches
{
    partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        private class SearchResult
        {
            public Collection<string> Missings;
            public Dictionary<string, int> Matches;

            public SearchResult()
            {
                Matches = new Dictionary<string, int>();
                Missings = new Collection<string>();
            }
        }

        private int FindMatchingWords( string[] pList, string pSearchWord )
        {
            int oResult = 0;
            foreach ( string Word in pList )
            {
                if ( Word.Equals(pSearchWord, StringComparison.OrdinalIgnoreCase) )
                {
                    oResult++;
                }
            }
            return oResult;
        }

        private string[] splitWords( string pList )
        {
            return pList.Split(new char[] { ' ', '\t', '\n', '\r', '.', ',', '?', '!'
                                            , ';', '/', '\\', ')', '(', '*','[', ']'
                                            ,'\"', '\'', '<', '>', '|' }
                               , StringSplitOptions.RemoveEmptyEntries);
        }

        private SearchResult Search( string pSearchWords, string pCompareWords )
        {
            string[] lpSearchWords = splitWords(pSearchWords);
            string[] lCompareWords = splitWords(pCompareWords);
            Dictionary<string, int> Occurances = new Dictionary<string, int>(lpSearchWords.GetLength(0));

            foreach ( string SearchWord in lpSearchWords )
            {
                if ( !Occurances.ContainsKey(SearchWord) )
                    Occurances.Add(SearchWord
                                  , FindMatchingWords(lCompareWords, SearchWord));
            }

            SearchResult oResults = new SearchResult();

            foreach ( KeyValuePair<string, int> Entry in Occurances )
            {
                if ( Entry.Value == 0 )
                {
                    oResults.Missings.Add(Entry.Key);
                }
                else
                {
                    oResults.Matches.Add(Entry.Key, Entry.Value);
                }
            }
            return oResults;
        }

        private void CountClick( object sender, EventArgs e )
        {
            SearchResult searchResults;
           
            if ( sender == LeftInRightMenuItem )
                searchResults = Search(txtLeft.Text, txtRight.Text);
            else
                searchResults = Search(txtRight.Text, txtLeft.Text);

            LeftInRightMenuItem.Checked = ( sender == LeftInRightMenuItem );
            RightInLeftMenuItem.Checked = !LeftInRightMenuItem.Checked;

            #region Adding LV Items...
            ListViewGroup lvGrpMiss = lvMatches.Groups[0];
            ListViewGroup lvGrpMatch = lvMatches.Groups[1];

            lvMatches.BeginUpdate();

            lvMatches.Items.Clear();

            foreach ( KeyValuePair<string, int> Match in searchResults.Matches )
            {
                lvMatches.Items.Add(new ListViewItem(new string[2] { Match.Key, Match.Value.ToString() }
                                                     , lvGrpMatch));
            }


            foreach ( string Miss in searchResults.Missings )
            {
                lvMatches.Items.Add(new ListViewItem(Miss, lvGrpMiss));
            }

            lvMatches.EndUpdate();
            #endregion

            #region StatusStripes...
            statusStripCountMissings.Text = string.Format("{0} missing words"
                                                 , searchResults.Missings.Count);
            statusStripCountMatches.Text = string.Format("{0} matching words"
                                                        , searchResults.Matches.Count);
           
            #endregion
           
            GC.Collect();
        }
    }
}

Gambit 23. Aug 2004 21:48

Re: Prüfen ob Wörter in einem String vorkommen, Reihenfolge
 
@Lutz: kann es sein, dass da irgendwas noch nicht stimmt an der isCharAlpha2 ? Dat funzt nämlich nicht mehr damit. Also ich habe die Funktion mit reingepackt und tausche beim Aufruf einfach nur isCharAlpha gegen isCharAlpha2 aus...

Gambit

P.S ach ne, geht doch, sorry

lume96 23. Aug 2004 22:27

Re: Prüfen ob Wörter in einem String vorkommen, Reihenfolge
 
Hab kein Delphi zuhause und konnte sie daher nicht testen, wüsste aber nicht warum sie nicht funktionieren sollte.

Nur um Missverständnisse auszuschliessen, die Linie alphachar muss komplett zumindest so aussehen :

Delphi-Quellcode:
const
 alphachar = 'abcdefghijklmnopqrstuvwxyz1234567890';
Ich war nur zu faul alle Buchstaben aufzulisten, deshalb die "...".

Du kannst sie noch durch Umlaute ergänzen, wenn Du willst.

Die Linie
Delphi-Quellcode:
result := (Pos(lowercase(mychar),alphachar)>0);
tut folgendes :

Pos(lowercase(mychar),alphachar) testet ob 'mychar' in 'alphachar' vorkommt und gibt die Position zurück. Soll heissen, wenn mychar einer der Buchstaben/Ziffern der Alphacharkonstante ist, so ist Pos() grösser als 0. Damit wäre dann (Pos() > 0) wahr und somit Result := wahr.

Das lowercase(mychar) bewirkt, dass eventuelle Grossbuchstaben in Kleinbuchstaben umgewandelt werden. Daher sind dann 'ABC...XYZ' in der alphachar nicht nötig.

So, wenn's trotzdem nicht klappt, einfach noch mal Bescheid sagen.

Tschüss,
Lutz

Gambit 23. Aug 2004 22:34

Re: Prüfen ob Wörter in einem String vorkommen, Reihenfolge
 
doch, klappt ja. Ich kann nun schön meinen String zerlegen. Wie gesagt, ich weiß nun aber nichts mehr so recht was ich damit anfangen soll, da ich das ja nicht in eine SQL-Anweisung einbauen kann.

Ich hatte ja vor, wenn ich einen Titel "Odysee im Weltall, 2001:" habe, den in "2001: Odysee im Weltall" zu finden, wenn du dich erinnern kannst.

Bin da ganz vom Wege abgekommen...

Gambit

Gambit 23. Aug 2004 23:47

Re: Prüfen ob Wörter in einem String vorkommen, Reihenfolge
 
@ Lutz:
ich habe wohl jetzt die Lösung gefunden. Ich löse also den Suchstring in einzelne Wörter auf, die ich in die Stringliste schreibe. In einer Schleife bastele ich mir dann daraus die Select-Anweisung zusammen ungefähr nach dem Motto:

SQL-Code:
select * from Table2 where (Titel like '%SList[0]%') and (Titel like '%SList[1]%') usw.
Damit habe ich zumindest die Gewähr, dass alle Wörter in dem String der Table2 vorkommen müssen, egal in welcher Reihenfolge.

So in Etwa, wenn ich nicht zu müde bin. Werds morgen mal ausprobieren...

Guts Nächtle

Gambit

lume96 24. Aug 2004 08:42

Re: Prüfen ob Wörter in einem String vorkommen, Reihenfolge
 
Sollte klappen, z.B. so :
Delphi-Quellcode:
   querystr := 'select * from datenbank2'; // querystr ist eine string var die das SQL-Statement enthält

   if SList.Count > 0 then
   querystr := querystr + #10 + #13 + 'where titel like ''%'+SList[0]+'%''';

   i := 1; // i ist eine locale integer variable
   while i <= SList.Count-1 do
   begin
      querystr := querystr + #10 + #13 + 'and titel like ''%'+SList[i]+'%''';
      inc(i);
   end;

   Query1.SQL.Add(querystr);
Tschüss,
Lutz

Gambit 24. Aug 2004 08:48

Re: Prüfen ob Wörter in einem String vorkommen, Reihenfolge
 
genau so hatte ich mir das gedacht!

Besten dank nochmal für die Hilfe, das gilt nat. für alle!

Gambit

mirage228 24. Aug 2004 08:58

Re: Prüfen ob Wörter in einem String vorkommen, Reihenfolge
 
Zitat:

Zitat von Robert_G
Falls du ein wenig in .Net interessiert bist...

Ich habe gerade aus "Jux" das Ganze mal in C#2.0 gebastelt (die Beta gibt's kostenlos bei M$ ;) )
Es ist nicht wirklich "hübsch", war aber in 10 Minuten fertig. (mit "IntelliSense tippt man schneller als ein MaiKäfer husten kann :P)

Hoi,

nettes kleines Programm - funktioniert einwandfrei bei mir ;)

Aber was lustiges ist mir aufgefallen:
Wenn ich das Programm direkt als Anhang öffne wird es in der Internet-Zone gestartet und aus "Sicherheitsgründen" wird das Menü nicht gezeichnet (Security Exception, Methode System.Drawing.CopyFromScreen) :mrgreen:
Ich bin mir sicher, dass das Menü meine Sicherheit gefährdet ;)

mfG
mirage228

Robert_G 24. Aug 2004 10:43

Re: Prüfen ob Wörter in einem String vorkommen, Reihenfolge
 
Zitat:

Zitat von mirage228
Ich bin mir sicher, dass das Menü meine Sicherheit gefährdet ;)

Jupp, ist ein CIA Menü :mrgreen:
Nein, in wirklichkeit ist das ein Bug in der 2.0 Beta des FrameWorks. Eine Assembly, die über das Internet aufgerufen wird hat ziemlich strikte Einschränkungen, deshalb knallt es bei den Kopieraktionen im Menu. ;)

Aike 7. Okt 2004 20:07

Re: Prüfen ob Wörter in einem String vorkommen, Reihenfolge
 
Ich finde das alles sehr kompliziert und versuche mehr durch Raten als durch Wissen zum Ziel zu kommen :cry:

Aber immerhin bin ich jetzt schon so weit gekommen, dass die Internetseite heruntergeladen und durchsucht wird. Leider kann ich nur nach einem einzigen String suchen und ihn auswerten. Sobald ich versuche, einen zweiten String auszuwerten, kriege ich eine Exception (Listenindex überschreitet das Maximum (1)).

Delphi-Quellcode:
var
  SpielerListe : String;
  sl  : TStringList;
  ndx : Integer;
  okay : Boolean;
  i:integer;
begin
  //HTML-Seite wird heruntergeladen und gespeichert
  okay := False;
  sl := TStringList.Create;
  try
    sl.Delimiter := ' ';
    for i:=0 to sl.Count-1 do
    begin
      sl.DelimitedText := memGesucht.Lines[i];
      for ndx := 0 to pred (sl.Count) do
      begin
        okay := Pos (sl.Strings[ndx],SpielerListe) > 0; // Wort ist vorhanden
        if not (okay) then
        begin
          memGetrennt.Lines.Add(sl.Strings[ndx]);
        end
        else
        begin
          memVerbunden.Lines.Add(sl.Strings[ndx]);
        end;
      end;
    end;
  finally
    FreeAndNil (sl);
  end;
end;

SaschaM 7. Okt 2004 23:11

Re: Prüfen ob Wörter in einem String vorkommen, Reihenfolge
 
es geht aber auch ohne schleife: TStringlist kann beim Hinzufügen von Duplikaten mit einem Fehler reagieren; vorallem ist das optimierter, da sortiere Stringlisten Quicksort verwendet.(vorallem wenn beide Listen lang sind!!) Ich habe das auch mal gebraucht, habe das dann so gelöst:


Delphi-Quellcode:
function IstVorhanden(CommaText1, Commatext2 : String; DelimiterChar: String) : Boolean;
var
  tstr1, tstr2 : TStringList;

begin
   tstr1 := TStringList.Create();
   tstr2 := TStringList.Create();

   try
     with tstr1 do begin
       Sorted := True; // ! wichtig, sonst geht das ganze nicht
       Duplicates := dupIgnore;
       Delimiter := DelimiterChar;
       DelimitedText := CommaText1;
     end;

     with tstr2 do begin
       Sorted := True; // ! wichtig, sonst geht das ganze nicht
       Duplicates := dupIgnore;
       Delimiter := DelimiterChar;
       DelimitedText := CommaText2;
     end;

     with tstr1 do begin
      Duplicates := dupError;
       try
         AddStrings(tstr2);
         Result := False;
       except
         Result := True;
       end;
     end;
   finally
     tstr1.Free;
     tstr2.Free;
   end;
end;
[edit=Luckie][ delphi]-Tags eingefügt. Beim nächsten mal bitte selber machen. Mfg, Luckie[/edit]

Aike 8. Okt 2004 17:19

Re: Prüfen ob Wörter in einem String vorkommen, Reihenfolge
 
Tut mir Leid, aber mit dem Quelltext kann ich kaum was anfangen, weil es für mich kaum einen Bezug zu meinem Problem bzw. meinem Quelltext darstellt.

Was bedeuten die zwei StringLists? In welche muss ich meine HTML-Datei laden und in welche meine Suchwörter?
Wieso wird "Delimiter" in der Funktion übergeben? Kann ich das auch irgendwo einfach mit Leerzeichen oder "*" definieren?
Was ist CommaText1 und CommaText2?
Was bewirkt die Anweisung ...
Delphi-Quellcode:
with tstr1 do begin
  Duplicates := dupError;
  [...]
end;
sorry, aber ich bin nicht so gut in Delphi :-/

SaschaM 8. Okt 2004 17:49

Re: Prüfen ob Wörter in einem String vorkommen, Reihenfolge
 
Aike, du hast zwei Listen, die Du miteinander vergleichen willst; die Daten sind entweder schon in zwei Stringlisten gespeichert oder noch als Text, getrennt mit einem beliebigen Zeichen (zb [,] oder [Leerzeichen]).

Du willst entweder wissen, ob zumindest ein String in der Liste des anderen vorkommt (siehe Code) oder ob alle übereinstimmen. Anstatt mit einer for i:= ... Schleife durchzulaufen, kannst du das sie Stringlisten für dich erledigen lassen. Die Parameter Commatext1 und Commatext2 sind die beiden Listen; Delimiter gibt an, welches Zeichen die einzelnen Elemente trennt.

Wichtig ist, daß

Delphi-Quellcode:
TStringList.Sorted := True
eingestellt ist, sonst klappt das ganze nicht so.

Mit der Eigenschaft TStringList.Duplicate kannst du angeben, wie eine Stringliste auf Duplikate reagieren soll (siehe Delphi-Hilfe); ein weitere Hinzufügen von Elementen mittels AddStrings oder Add wird dann entsprechend gesteuert (dupIgnore = nichts tun, dupError: Fehler auslösen, dupAccept = Duplikat hinzufügen);

so erhälst Du durch:


Delphi-Quellcode:
     
with tstr1 do begin
   Duplicates := dupError;
   try
      AddStrings(tstr2);
      Result := False;
   except
      Result := True;
   end;
end;
True, sobald nur ein Element in der anderen Liste vorhanden ist.

Oder, Du willst einen Vergleich auf ALLE Elemente: Du läßt alle Elemente hinzufügen, gibst aber an, daß Duplikate nicht erlaubt sind: Ist die Anzahl der Elemente vorher gleich hoch wie nachher, waren alle gleich:

Delphi-Quellcode:
with tstr1 do begin
   Duplicates := dupIgnore;
   AnzahlElemente := tstr1.Count;
   AddStrings(tstr2);
   Result := (AnzahlElemente = tstr1.Count);
end;
klar?
sascha

Aike 8. Okt 2004 18:18

Re: Prüfen ob Wörter in einem String vorkommen, Reihenfolge
 
Also, ich hab den Quelltext einfach eingefügt und ausprobiert, aber es findet nichts in der Liste :-/
(Wie oft das Wort vorkommt, ist egal, höchstens ob zwei Strings aufeinander folgen, wäre schön zu wissen, z.B. "Guten Appetit")

Delphi-Quellcode:
SpielerListe := getHTML('http://www.d4o.de/index.php?site=heldenonline'); //SpielerListe ist ein String

if IstVorhanden('aktuell',SpielerListe,',') then //Wort "aktuell" kommt auf jeden Fall vor
  ShowMessage('Online')
else
  ShowMessage('Offline');

SaschaM 8. Okt 2004 18:58

Re: Prüfen ob Wörter in einem String vorkommen, Reihenfolge
 
Zitat:

Zitat von Aike
Also, ich hab den Quelltext einfach eingefügt und ausprobiert, aber es findet nichts in der Liste :-/
(Wie oft das Wort vorkommt, ist egal, höchstens ob zwei Strings aufeinander folgen, wäre schön zu wissen, z.B. "Guten Appetit")

Delphi-Quellcode:
SpielerListe := getHTML('http://www.d4o.de/index.php?site=heldenonline'); //SpielerListe ist ein String

if IstVorhanden('aktuell',SpielerListe,',') then //Wort "aktuell" kommt auf jeden Fall vor
  ShowMessage('Online')
else
  ShowMessage('Offline');


Kannst Du die Funktion für getHTML posten oder die Liste an sich??

Gruß Sascha

Aike 8. Okt 2004 19:10

Re: Prüfen ob Wörter in einem String vorkommen, Reihenfolge
 
Die Funktion "GetHTML" habe ich hier (www.delphipraxis.net) her.

Aike 17. Okt 2004 22:43

Re: Prüfen ob Wörter in einem String vorkommen, Reihenfolge
 
Ich habe es jetzt wie folgt hinbekommen:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  DelphiPraxisStrings : String;
  sl  : TStringList;
  ndx : Integer;
  okay : Boolean;
  x:integer;
begin
  DelphiPraxisStrings := getHTML('http://www.delphipraxis.net'); //Nur als Bsp.

  lstbxGetrennt.Items.Clear;
  lstbxVerbunden.Items.Clear;

  sl := TStringList.Create;
  try
    sl.Delimiter := ' ';
    sl.Sorted:=True;

    for x:=0 to lstbxGesucht.Count-1 do
    begin
      sl.DelimitedText := lstbxGesucht.Items[x];
      sl.Duplicates:=dupIgnore;
      for ndx := 0 to pred (sl.Count) do
      begin
        okay := Pos (sl.Strings[ndx],DelphiPraxisStrings) > 0; // Wort ist vorhanden
        if not (okay) then
        begin
          lstbxGetrennt.Items.Add(sl.Strings[ndx]); //Wort steht nicht in der Liste
        end
        else
        begin
          lstbxVerbunden.Items.Add(sl.Strings[ndx]); //Wort steht in der StringListe
        end;
      end;
    end;
  finally
    FreeAndNil (sl);
  end;
end;
Jetzt fehlt mir nur noch eine Möglichkeit auch aufeinander folgene Strings zu untersuchen ... wie eben "Guten Tag", welches in "lstbxGesucht.Items[x]" gespeichert ist.

Mir ist leider gerade aufgefallen, dass auch Substrings gefunden werden. In diesem Thread steht ja schon etwas von der function "SplitIntoWords", aber ich weiß nicht, was ich damit anfangen soll :wiejetzt:

SaschaM 18. Okt 2004 12:53

Re: Prüfen ob Wörter in einem String vorkommen, Reihenfolge
 
Sorry, Aike, hatte keine Zeit in den letzten Tagen...

Ich habe nun nicht ganz mitbekommen, was Du eigentlich haben willst.

Wofür stehen nun die 3 Variablen:

lstbxGetrennt
lstbxVerbunden
DelphiPraxisStrings

und was willst du als Ergebnis erhalten?

lg
Sascha

Aike 19. Okt 2004 09:22

Re: Prüfen ob Wörter in einem String vorkommen, Reihenfolge
 
lstbxGetrennt enthält alle nicht vorhandenen Wörter; lstbxVerbunden enthält alle enthaltenen Wörter; DelphiPraxisStrings enthält alle Wörter auf der DelphiPraxis-Startseite.

Das Ergebnis sollte so aussehen:
"Tölz" -> Nicht enthalten -> lstbxGetrennt
"Delphi" -> Enthalten -> lstbxVerbunden

"Delp" -> Nicht enthalten -> lstbxGetrennt
"Willkommen in der freundlichen Community" -> Enthalten -> lstbxVerbunden


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