String durchsuchen nach mehreren Begriffen

  • VB.NET

Es gibt 19 Antworten in diesem Thema. Der letzte Beitrag () ist von RISSN.

    String durchsuchen nach mehreren Begriffen

    Hallo,

    ich nutze VB.NET in VS2017 und würde gerne einen String durchsuchen der mehrere Treffer haben kann. Also dazu lese ich Werte aus einer SQL Datenbank und vergleiche einen Wert dann mit einem vordefinierten Text den man auch ändern kann. Dort soll es jetzt möglich sein, dass ich mehrere Begriffe habe. Als Beispiel kommt aus der Datenbank der Text "mein Auto kann schnell fahren" und in meinem Vergleich steht "meinAutolangsam". Wenn ich jetzt mit Contains arbeite, dann ist ja das Ergebnis True. Ich möchte aber schauen ob eines der Wörter dort vorkommt, also "mein" "Auto" oder "langsam". Wie kann ich das am besten machen? Vielen Dank schon einmal für eure Hilfe.

    RISSN schrieb:

    Wenn ich jetzt mit Contains arbeite, dann ist ja das Ergebnis True.
    du musst Contains mehrmals anwenden - für jedes Wort aus der Datenbank einmal.
    Mit Linq.Any kann man das recht elegant abfrühstücken:

    VB.NET-Quellcode

    1. Dim dbWords = "mein Auto kann schnell fahren".Split
    2. Dim vergleich = "meinAutolangsam"
    3. Dim schauen_ob_eines_der_Wörter_dort_vorkommt as boolean = dbWords.Any(Function(x) vergleich.Contains(x))

    Erstmal Danke für deine Antwort. Ich glaube der Ansatz ist ganz gut. Aber bei mir bleibt der Vergleich leer. Ich habe im als Suchbegriff als Beispiel 3 Wörter, die schreibe ich mit leerzeichen dort rein und will diese mit einem Wert aus der Datenbank vergleichen. Aber der Wert aus der Datenbank hat ein Wort oder einen Text der länger sein kann. Es muss eben der Inhalt von eines der 3 Wörter da drin auftauchen. Weiterhin muss ich auch in lower oder upper umwandeln, da ich nicht weiß, wie es in der Datenbank steht. Also Split.ToString.ToLower - aber dann steht nichts mehr in der Variable "Vergleich"

    Zitat entfernt. ~Thunderbolt

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Thunderbolt“ ()

    Ich habe mich bestimmt falsch ausgedrückt. Sorry. Aus der Datenbank lese ich "ich_bin_ein_Auto" und haben im Setup eine Textbox deren Inhalt mir nicht bekannt ist. Lediglich weiße ich darauf hin, ein Leerzeichen zwischen den Begriffen zu lassen. Dort steht jetzt als Beispiel drin "bin Fahrrad". Jetzt sollte beim vergleichen das "bin" gefunden werden. Auch wenn es "Auto" findet, dann sollte die Funktion erfüllt sein. Ich weiß nicht, ob ich mich schon wieder komisch ausdrücke

    Ich glaube deine Funktion oben funktioniert schon ganz gut, nur wenn ich diese jetzt umwandel in Split.ToString.ToLower dann steht nicht mehr in dbWords drin. Also wäre das jetzt noch das Problem, wie kann ich die Groß und Kleinschreibung ignorieren? Vielen Dank

    Zitat entfernt. ~Thunderbolt

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Thunderbolt“ ()

    RISSN schrieb:

    Ich glaube deine Funktion oben funktioniert schon ganz gut
    DAs heisst, du konntest dich dessen noch nicht vergewissern.
    Übrigens ist das keine Funktion - es sind nur drei Zeilen Code.

    Ich könnte dir eine Funktion schreiben, die überprüft, ob in einer Liste von Strings mindestens einer enthalten ist, der als Teilstring in einem Vergleichs-Wort vorkommt.
    Aber ich bezweifel, dass du die Funktion sinnvoll einbauen könntest.
    Ich bezweifel, ob du überhaupt so eine Funktion brauchst, oder nicht doch irgendwie eine andere.

    Am besten wäre, du codest die Funktion, wie du sie brauchst und einbauen könntest. Sie muss nichts enthalten - die innere logik könnte ich übernehmen.
    Sie darf sogar nichts enthalten (bzw. ich würde es sicherlich löschen und korrigiert hinschreiben).

    An so einer Funktion könnte ich klar erkennen, was du brauchst - auch wenn du es in Worten nicht eindeutig genug formulieren kannst.

    Etwa bisher hast du formuliert: "Ich suche eine Funktion, die überprüft, ob in einer Liste von Strings mindestens einer enthalten ist, der als Teilstring in einem Vergleichs-Wort vorkommt."
    Das sähe dann so aus:

    VB.NET-Quellcode

    1. private function CheckCandidates(candidates as List(Of String), wordToCompare as String) as Boolean
    2. '... logik...
    3. End Function
    Aber wie gesagt: Das ist zwar, was du bisher bestellt hast, aber ich glaube nicht, dass du es brauchen kannst.
    Falls ich mich irre, und du kannst es doch brauchen, sag bescheid, dann kann ich das auch eben ausfüllen.

    Aber wieder wie gesagt: Schreib du den Function-Rumpf - ich kann dir das eiglich nicht abnehmen.
    Hallo,

    ja, deine 3 Zeilen Code funktionieren tatsächlich. Ich dachte nur, wenn ich diese jetzt in upper oder lower umwandel geht sie auch noch. Leider nein. In der Datenbank kann ja sein das dort vielleicht klein oder mal Groß geschrieben wird. Ich habe es jetzt so gemacht wie du oben schon richtig beschrieben hat.

    VB.NET-Quellcode

    1. Dim dbWords = My.Settings.SearchString.Split
    2. Dim Vergleich = myData(13).ToString.ToUpper
    3. Dim IsSearchWord As Boolean = dbWords.Any(Function(x) Vergleich.Contains(x))

    Bei der Eingabe der Suchwerte wandel ich jetzt einfach alles in Großbuchstaben um. Dann funktioniert es so wie es soll, ich dachte man kann zum Beispiel auch

    VB.NET-Quellcode

    1. Dim dbWords = My.Settings.SearchString.Split.tostring.toUpper - ist der eingegebene Suchbegriff
    2. Dim Vergleich = myData(13).ToString.ToUpper - ist das was ich aus der Datenbank lese
    3. Dim IsSearchWord As Boolean = dbWords.Any(Function(x) Vergleich.Contains(x))

    machen, dann bleibt die Variable dbWords allerdings leer..

    Vielen Dank für deine Hilfe, ich bin ja schon zufrieden, dass es schon mal funktioniert

    CodeTags gesetzt ~VaporiZed

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „VaporiZed“ ()

    My.Settings.SearchString.Split.tostring.toUpper - das hast Du offensichtlich nicht getestet. Da kommt nämlich Blödsinn raus.

    Erst ToUpper, dann splitten.

    Warum eigentlich ToString? Ist doch schon einer.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Hallo,

    ja genau, dass schrieb ich ja, es ging nicht so wie ich es benutzt habe. Aber so wie du geschrieben hast, erst ToUpper und dann Split geht wunderbar. Alles in allem bin ich zufrieden, es funktioniert wie es soll. Ich danke euch, ihr habt mir wirklich sehr geholfen, vielen vielen Dank.
    Ich sehe, meine Ausführung ist missverständlich. Was ich meinte, war gar nicht auf mein Beispiel bezogen, sondern auf:
    Dim dbWords = My.Settings.SearchString.Split.tostring.toUpperDarauf bezog sich meine Frage, obwohl man das gar nicht auf Anhieb erkennen kann. :/
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Neu

    Wenn eh alles in einer SQL-Datenbank liegt, warum nicht gleich mit SQL-Querys auslesen?
    Die Sucheingaben des Users auf Einzelstrings ohne Leerzeichen aufdröseln und dann jeden einzelstring in die SQL-Abfrage einbauen.

    SQL-Abfrage

    1. WHERE Datebankfeld='%mein%' and Datenbankfeld ='%Auto%'
    ....
    Liebe Grüße
    Roland Berghöfer

    Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): bocomponent.com | freeremarkabletools.com

    Neu

    ErfinderDesRades schrieb:

    RISSN schrieb:

    ... und geht wunderbar...
    Fein, dasses jetzt funzt.
    Wenn du viel lernen willst, kannst du deine Function hier ja posten.
    Ich vermute, sie wird noch stark verbesserungs-fähig sein.


    ich habe es genauso gemacht, wie du schon oben geschrieben hast, nur noch mir "ToUpper", es funktioniert allerbest. Möglich das man es noch verbessern kann, keine Ahnung, auf alle Fälle bin ich dankbar für dieses Ergebnis was ich bis hierhin habe.

    VB.NET-Quellcode

    1. Function KeyWord(DataBaseValue As String) As Boolean
    2. ' sucht in der Datenbankabfrage nach Übereinstimmungen
    3. Dim SingleWords = My.Settings.SearchString.ToUpper.Split 'alle Wörter in Array schreiben und in Grossbuchstaben umwandeln
    4. Dim DBValue = DataBaseValue.ToUpper 'Wert aus Datenbank in Grossbuchstaben umwandeln
    5. Dim IsSearchWord As Boolean = SingleWords.Any(Function(x) DBValue.Contains(x)) 'jetzt vergleichen und zwar alle Wörter die gefunden wurden[/color]
    6. ' Wert zurück geben ob etwas übereinstimmt
    7. Return IsSearchWord
    8. End Function

    CodeTags gesetzt ~VaporiZed

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VaporiZed“ ()

    Neu

    @petaod ja richtig. Das LIKE habe ich nicht geschrieben. Aber ich hoffe man konnte sehen was ich meinte ;-).
    Liebe Grüße
    Roland Berghöfer

    Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): bocomponent.com | freeremarkabletools.com

    Neu

    @RISSN: Ne Kleinigkeit:

    VB.NET-Quellcode

    1. Dim IsSearchWord As Boolean = SingleWords.Any(Function(x) DBValue.Contains(x)) 'jetzt vergleichen und zwar alle Wörter die gefunden wurden[/color]
    2. ' Wert zurück geben ob etwas übereinstimmt
    3. Return IsSearchWord
    ->

    VB.NET-Quellcode

    1. Return SingleWords.Any(Function(x) DBValue.Contains(x)) 'jetzt vergleichen und zwar alle Wörter die gefunden wurden
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Neu

    Ok, dass macht es gleich etwas schlanker und übersichtlicher. Cool.

    Ich weiß nicht ob man diese Frage jetzt hier stellen darf, oder ob man ein neues Thema aufmachen muss. Ist es möglich eine dll die für C+ ist, in VB.NET einzubinden? Unter Verweise kann man sie ja nicht einfach hinzufügen leider.

    Neu

    RISSN schrieb:

    VB.NET-Quellcode

    1. Function KeyWord(DataBaseValue As String) As Boolean
    2. ' sucht in der Datenbankabfrage nach Übereinstimmungen
    3. Dim SingleWords = My.Settings.SearchString.ToUpper.Split 'alle Wörter in Array schreiben und in Grossbuchstaben umwandeln
    4. Dim DBValue = DataBaseValue.ToUpper 'Wert aus Datenbank in Grossbuchstaben umwandeln
    5. Dim IsSearchWord As Boolean = SingleWords.Any(Function(x) DBValue.Contains(x)) 'jetzt vergleichen und zwar alle Wörter die gefunden wurden[/color]
    6. ' Wert zurück geben ob etwas übereinstimmt
    7. Return IsSearchWord
    8. End Function
    Ich bin höchst angenehm überrascht: Die Methode ist angemessen und effektiv.
    Einzig Benamung und Kommentation wäre korrekturbedürftig.
    Zuerst Benamung:Die Methode gibt kein KeyWord zurück, dann soll sie auch nicht KeyWord() heissen. Sie prüft einen String, ob er ein(es der) KeyWords enthält - also heisst sie: ContainsKeyWord()
    Die Methode überprüft auch keinen DataBaseValue, sondern sie kann jeden beliebigen String überprüfen - einfach s
    In der Methode gibts ein SingleWords - das sind doch die KeyWords, gegen die der String abgeglichen wird. Dann sollen die doch keyWords heissen.
    DBValue ist überhaupt kein DBValue - ist einfach nur ein Upper-String. Ich würd die Variable ganz überflüssig machen.
    IsSearchWord ist gar kein Wort, und sagt auch nicht aus, ob irgendetwas ein SearchWord ist. Sondern es ist ein Boolean, der aussagt, ob s eines der KeyWords enthält. Müsste also ContainsKeyWord heissen - aber das geht nicht - so heisst ja schon die Methode. Dann nenn sie einfach result, denn tatsächlich ists ja genau das: das Ergebnis der Function
    Gesamtergebnis:

    VB.NET-Quellcode

    1. Function ContainsKeyWord(s As String) As Boolean
    2. ' sucht in der Datenbankabfrage nach Übereinstimmungen
    3. Dim keyWords = My.Settings.KeyWords.ToUpper.Split 'alle Wörter in Array schreiben und in Grossbuchstaben umwandeln
    4. s = s.ToUpper 'Wert aus Datenbank in Grossbuchstaben umwandeln
    5. Dim result As Boolean = keyWords.Any(Function(x) s.Contains(x)) 'jetzt vergleichen und zwar alle Wörter die gefunden wurden[/color]
    6. ' Wert zurück geben ob etwas übereinstimmt
    7. Return result
    8. End Function


    So, jetzt Kommentation - nur ein einziger Kommentar stimmt, und der ist überflüssig - aber zeilefürzeile:
    • #2 In der Methode wird in keiner Datenbankabfrage gesucht - Lüge! - weg damit.
    • #3 fast richtig - nur die Reihenfolge: Erst wird in Grossbuchstaben gewandelt - danach in ein Array geschrieben
      Klingt kleinlich dieser Unterschied, aber wenn man diesen Thread verfolgt, kamst du genau aufgrund dieses Irrtums 5h lang nicht weiter, und musste Vaporized aufklären (post#8+9)
      Man kann den Komment auch weglassen, weil steht da ja: .KeyWords.ToUpper.Split - in richtiger Reihenfolge - wozu also überhaupt der Kommentar?
    • #4 Der Wert ist nicht aus der Datenbank - wie gesagt: kann jeder String sein
    • #5 da wird doch nix verglichen. .Contains() - also die Prüfung der Existenz eines Inhaltes - das ist doch kein Vergleich.
      richtige Aussage wäre: "prüfen, ob s eines (any) der keyWords enthält"
    • #7 das ist unbestreitbar richtig. Und als Kommentar auch genauso überflüssig - denn steht da ja: Return result

    gut - also überarbeitete Methode:

    VB.NET-Quellcode

    1. ''' <summary>prüft, ob s eines der in den Settings festgelegten Keywords enthält (ignoring Case)</summary>
    2. Function ContainsKeyWord(s As String) As Boolean
    3. s = s.ToUpper
    4. Dim keyWords = My.Settings.KeyWords.ToUpper.Split
    5. Return keyWords.Any(Function(keyWord) s.Contains(keyWord))
    6. End Function
    Hab dem Teil sogar einen Doku-Kommentar spendiert.

    So, das liest sich wie ein totaler Verriss - aber wie gesagt: ist es gar nicht.
    Weil die Methode ist in Ordnung, funktional nicht zu verbessern.
    Es geht "nur" um Benamung und Kommentation. (Allerdings wird genau das ganz ganz ganz häufig total unterschätzt.)

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Neu

    Visual Basic-Quellcode

    1. ''' <summary>prüft, ob s eines der in den Settings festgelegten Keywords enthält (ignoring Case)</summary>
    2. Function ContainsKeyWord(s As String) As Boolean
    3. s = s.ToUpper
    4. Dim keyWords = My.Settings.KeyWords.ToUpper.Split
    5. Return keyWords.Any(Function(keyWord) s.Contains(keyWord))
    6. End Function


    ich gebe dir Recht, deswegen habe ich genauso übernommen. Vielen Dank, du achtest aber wirklich auf jedes kleine Detail, aber genauso ist es ja auch richtig.

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „RISSN“ ()