Regex anhand einer List of T erstellen

  • VB.NET

Es gibt 20 Antworten in diesem Thema. Der letzte Beitrag () ist von Phreak87.

    Regex anhand einer List of T erstellen

    Hallo Leute,

    kann mir jemand dabei helfen einen Regex-Generator zu erstellen ...
    Mir gehen da irgendwie die Ideen aus ...
    das ganze soll so funktionieren:

    Ich übergebe meiner funktion eine List of String mit mehereren Werten
    und möchte einen Regex-Pattern zurückbekommen, dass auf alle diese Werte
    zutrifft (Zumindest wenn möglich und nicht zu komplex) ...
    Zweck soll sein aus einer Liste ein Pattern zu erstellen und eine andere Liste
    mit diesem Pattern zu vergleichen.

    Das ganze soll beinhalten
    - Einfache Strings
    - Zahlen/Bereiche
    - Kein Inhalt
    - Datumsangaben
    - Immer gleicher Text ...

    z.B. wenn ich 20 Telefonnummern habe, die mit 0151 beginnen
    müsste er ausgeben 0151[Varianz nächste Stellen bzw. Zahlenbereich]*

    Kennt hier wer schon ein Projekt oder hat eine Idee wie man sowas umsetzen sollte ?

    Lg. Markus
    Dazu müsstest du alle Strings gegeneinander abgleichen.
    Darin gewisse "Fixe" Muster finden und danach ein Pattern finden welches auf den Rest passt, aber nicht mehr findet.

    Das wird so nicht gehen, zumindest nicht vollautomatisch.

    Folgendes Szenario:

    Die Texte:

    Test123
    Test345
    Test555

    Jetzt lässt du dein Programm suchen und es findet heraus das alle Strings mit "Test" beginnen.

    So weit, so gut.
    Aber nun muss dein Programm entscheiden welches Pattern für den hinteren Teil passt.

    Und hier kommen die Probleme. Dein Programm weiß nicht, ob nur diese Zahlen vorkommen dürfen oder alle Zahlen. Vl ist es ja eine nummerierung die nur bis 600 gehen darf. Vl willst du auch einfach nur genau die drei Texte usw.

    Das kann man einem Programm nicht beibringen (ausser mit ein paar hundert Schaltern).
    Am besten ist immer noch, das eigene Hirn zu benutzen, dass arbeitet nämlich auf diesem gebiet besser :D

    Als Hilfe kannst du txt2re.com/ verwenden.
    SWYgeW91IGNhbiByZWFkIHRoaXMsIHlvdSdyZSBhIGdlZWsgOkQ=

    Weil einfach, einfach zu einfach ist! :D
    Hallo,

    erstmal Danke für deinen Beitrag.
    Du hast recht dass das Programm nie 1000 %ig wissen kann was ich will.
    Für gewisse Dinge muss ich einfach "ein Auge zudrücken" und das ganze so
    genau wie möglich machen ... Die Funktion sollte nur eine Hilfe für den Benutzer sein
    was er sich nochmal genau ansehen sollte und was ganz aus dem "Raster fällt" ... bei ein paar
    tausend Datensätzen kann schon mal ein Bockmist mit dabei sein ... Das ganze soll als "grober
    Anhaltspunkt" dienen ...

    Ein besseres Beispiel mit einem Autohaus:

    Hier steht eine Liste mit Autos,Herstellern, Optionen und weiteren Infos zur Verfügung ...

    Marke, kW, PS, Artikelnummer, Zusatzausstattung PaketNr. ,Beschreibungstext

    BMW, 100, 170, A123456, A15, BliaBlaBlubb
    BMW, 170, 260, A124567, B24, LoremIpsum
    VW, 110, 160, B126789, Z27, Leberkäse heute gratis

    Dann habe ich die Varianz

    Marke = 2 = (BMW,VW) <- exakt!, geht nur bei Varianz kleiner Benutzervorgabe
    kW = 3 = 1[0-7]{2,2} <- Also kW von 100 bis 177 ... reicht als Genauigkeit
    Ps ... gleiches Spiel wie kw ... Genauigkeit passt.
    Artikelnummer ... Varianz 3 = A12[346][457]... <- passt
    Option (A|B|Z)[346][4-7]<- ginge auch, ausreichend genau ...

    So und dann das was du meinst ...

    Texte => hier wirds schlimm ... wenn möglich soll er es Auflösen, wenn nicht
    dann ein "TO COMPLEX" ausgeben ... damit weiß der Benutzer dass diese Felder
    einfach nicht geprüft werden können. Hier liegt das Hauptproblem des ganzen ..

    Ich habe schon einmal angebastelt und folgendes ist rausgekommen:

    Bei einem leeren Feld kommt immer "(^$| )"
    Wenn Varianz 1 dann Wert ausgeben
    Wenn Varianz < 20 dann Werte ausgeben [Wert1|Wert2]
    Wenn Varianz größer dann
    => Bei Zahlen 1234[1-9]{4,4} -> Somit ist zumindest die Länge und erste Stellen sichergestellt.

    => Bei Texten [aBg][zdk]... kann funktionieren, muss aber nicht ...
    hier liegt auch der große Hund begraben dass ganze in eine vernünftige Form
    zu packen ... Probleme gibts wenn da steht "A12345" weil er dann die Zahlen nicht
    als Zahlen auflöst und wenn etwas "reinrutscht" z.B "BMW Auto" und "BMW das Auto".
    richtig aufgelöst wäre BMW ?(das) Auto ... da komm ich einfach nicht weiter ... zudem sollte
    das Programm erkennen wann es sinnlos ist (z.B) bei Texten, die gar nicht zusammenpassen ...

    Hier fehlt mir noch was ... einfach die Buchstaben zusammenklatschen ist grottig [Azk][ind]...

    wie wäre hier das beste Vorgehen um an eine "einigermaßen" passable Lösung zu gelangen ?

    Phreak87 schrieb:

    "einigermaßen" passable Lösung zu gelangen ?

    Idee fallenlassen ...

    Mit Regex wird das IMHO schon mal gar nix. Im Prinzip geht es dir um eine KI, die (unbekannte) "Ähnlichkeiten" erkennt und daraus eine Regel erstellen kann, bzw "Abweichungen" von der selbsterstellten Ähnlichkeitsregel finden kann. Kniffelig!

    Im Prinzip steht die Kryptoanalyse vor einem ähnlichen (pun intended) Problem und dort ist es nur dann lösbar, wenn große Mengen Text zum untersuchen zur Verfügung stehen (da nur dann statistische Ausrutscher deutlich zu Tage treten). Vlt kannst du bei dir etwas Input sparen, weil es nicht komplett Zufall ist, was du bekommst, aber trotzdem wird das mit "einfachen" Mitteln imho unlösbar sein.
    Hi,

    Kniffelig ist die ganze Sache schon ... bei der künstlichen Intelligenz soll das Programm
    auch aussteigen. Die unbekannten Ähnlichkeiten wären eine 1000%-Lösung, die ich gar
    nicht anstrebe zu erreichen ... 50% würden mir reichen. Die Menge an Text umfasst in jeder
    Datenreihe ca. 30000 Sätze ... wenn das ganze zu heavy wird soll er ausgeben "TO COMPLEX" ...

    Ich stand heute vor dem Problem dass im Text 2 verschiedene Varianten des gleichen
    "Typs" nur anders geschrieben vorkommen.

    mal angenommen ich verarbeite folgende Wörter:

    OneX DualCore
    Handy OneX Dualcore
    Dualcore Handy OneX

    dann habe ich als Regex (primitiv) den Matchcode:
    [OHD][nau]...?[Cne]?[ocn]

    und auf ganze Wörter bezogener Regex (gefällt mir schon gut)
    [OneX|Handy|DualCore][DualCore|OneX|Handy]?[DualCore|OneX]

    schick wäre hier ... (Mir fällt selbst nicht mehr ein ...)
    ?[Handy|DualCore]OneX?[DualCore|OneX]

    wahrscheinlich wäre das schon ein Fall für KI also -> Nicht lösbar ...

    gehen sollte es bei -> Der Fall der mich plagt !

    OneX Handy DualCore
    OneX Dualcore

    Da sollte er ausgeben:
    OneX ?[Handy] Dualcore
    Dieser Fall wäre noch zu erreichen weil Pat1 immer gleich,
    Pat2 Optional und Pat3 einmal Pat2 und einmal Pat3 ist ...
    Anzahl min = 2, Anzahl max = 3
    Mit stupidem rantasten und testen komme ich an das gewünschte Ergebnis
    und habe 4 Tests vor mir:

    Test1: Pat1 + Pat2 -> Fail
    Test2: Pat1 + Pat3 -> Fail
    Test3: Pat1 + ?Pat3 + Pat2 -> Fail
    Test3: Pat1 + ?Pat2 + Pat3 -> OK!

    bei 4 wirds dann schon komplexer ...

    Bleibt spannend ...
    IMHO bist du mit Regex immer noch schwer auf dem Holzweg. Wäre aber vermutlich einfacher, wenn du uns erstmal erklärst WAS du überhaupt genau willst und nicht danach fragst wie du DEINE Lösung am besten umsetzt - denn die ist ggf ja gar nicht die richtige.

    Du hast also Datensätze und suchst darin ... was? Ähnliche? "Falsch" geschriebene "Worte" (Handy vs Hnady?)?
    Im persönlich glaube, dass du eher im Bereich Phonetik etc fündig werden wirst. Soundex, Levenshtein, Q-Grams etc.
    Hi,

    dann fang ich mal an zu erklären was ich eig. vorhabe ...
    Ich habe mehrere verschiedene Dateien, teilweise Datenbanken
    aber auch Excel-Dateien oder reine Textfiles (bis 30 MB) die ich verarbeiten muss.
    Die Inhalte unterscheiden sich dabei sehr, weshalb ich keine eindeutige Aussage zu einem ganz bestimmten
    Vorgehen machen kann. Ich Importiere die Daten dann in mein Programm und kann
    mir z.B. einen SQL-Select (Mit Vorgaben) aus den verschiedenen Spalten generieren lassen bzw.
    verschiedene Aufgaben bei den Dateien durchführen (dazu gehört auch das Speichern in
    einem gewissen definierten Format und andere Exportfunktionen. Desweiteren kann es eine
    Distinct bzw. (Begriff entfallen) ... Ich nenne es "Reverse Distinct" ... Also alle dubletten anzeigen .

    Somit ein Massentexttoolkit. Teilweise muss ich die Inhalte mit anderen Daten nachbilden, weshalb ich
    eine möglichst genaue (aber sicher nicht perfekte) lesbare "Übersicht" der Inhalte erstellen möchte (Der Regex Plan).
    Das Programm bietet mir für die Zieldaten einen 2. Arbeitsbereich an ... Funktionsweise dann folgendermaßen ... Import Original in
    Liste 1, Pattern erstellen, groben SQL-Select generieren, Datenbank mit anderen Daten aufbauen, wieder in das Programm
    in Liste 2 importieren und dann Querchecken mit Pattern von Liste 1.

    Weil ich ja weiß wo die Texte nicht übereinstimmen (können) ist eine gewisse Ungenauigkeit mit berücksichtigt und auch
    selbstverständlich. Bei den Daten handelt es sich meist um ziemlich "explizite" Daten sprich Artikelnummern, Geräte der gleichen
    Baureihe, die die eigenschaften im Typenschlüssel definieren, sowie Textfelder, die diese Inhalte nochmals Textmäßig beschreiben
    (Weshalb ich hier Regex sehr angebracht finde). Die Varianten der Felder (Also Distinct) Filtert mir *meistens* die Datensätze der
    Spalte von 3000 schon auf 10 (weil ja immer die gleichen Eigenschaften verwendet und Textmäßig beschrieben werden).

    Du hast also Datensätze und suchst darin ... was? Ähnliche? "Falsch" geschriebene "Worte" (Handy vs Hnady?)?
    -> Dieser Satz würde in der Zielliste als Fehlerhaft markiert ! Ähnliche Worte suche ich auch nicht. Nur Explizite Worte.

    Im persönlich glaube, dass du eher im Bereich Phonetik etc fündig werden wirst. Soundex, Levenshtein, Q-Grams etc.
    Q-Grams habe ich mir angesehen und klingt sehr interessant, wäre aber für mein Vorhaben unbrauchbar.

    Das Programm soll mir also (so gut als möglich) einen Regex Pattern präsentieren, dass auf alle Sätze der Quellliste zutrifft.
    Die Zielliste sollte dann nur die Abweichungen von der Quelle anzeigen und muss zwingend mit Kopf nochmals betrachtet werden.
    und an dem "so gut als möglich" hakt es noch gewaltig an den Texten, die Freitext sind bzw. im Zieldatenformat keine fest vorgegebene
    Definition haben.

    Montag werde ich vielleicht Screenshots und Code posten.
    Noch eine Frage zu Regex ...

    der Code

    MsgBox(System.Text.RegularExpressions.Regex.IsMatch("22.17", "[0-9]{3,5}")) ergibt falsch
    und
    MsgBox(System.Text.RegularExpressions.Regex.IsMatch("222.17", "[0-9]{3,5}")) ergibt true

    ... wieso lässt regex Nachkommastellen zu, wenn ich das nicht explizit definiere habe ?
    und wie definiere ich es dann demnach ? wenn ich überprüfen will ob eine Zahl 2 Nachkommastellen
    hat o.Ä.
    Dein Pattern reagiert auf drei, maximal fünf Zahlen in Reihenfolge. Der Punkt funkt beim ersten Ausschnitt dazwischen.
    „Was daraus gefolgert werden kann ist, dass jeder intelligentere User sein Geld lieber für Bier ausgibt, um einen schönen Rausch zu haben, und nicht dieses Ranzprodukt.“

    -Auszug aus einer Unterhaltung über das iPhone und dessen Vermarktung.
    Achso ... :D

    stimmt ...

    MsgBox(System.Text.RegularExpressions.Regex.IsMatch("22.157", "[0-9]{3,5}"))
    macht mir dann auch ein True draus ... dann macht ers ja richtig dann müsste es
    einfacherhalbe nur MsgBox(System.Text.RegularExpressions.Regex.IsMatch("22.157", "[0-9]{2,3}[.|,][0-9]{2}")) lauten
    wenn der Dezimaltrenner nicht fest steht ...

    Merci ;)

    VB.NET-Quellcode

    1. Private Function Regex_Zahlen(Text As List(Of String)) As String
    2. Dim INT1 As New List(Of Double)
    3. Dim INT2 As New List(Of Double)
    4. Dim Match As String = ""
    5. For Each Eintrag As Double In Text
    6. INT1.Add(Math.Round(Eintrag, 0))
    7. INT2.Add(Mid(CStr(Eintrag), Len(CStr(Math.Round(Eintrag, 0))) + 2))
    8. Next
    9. Match = "[0-9]{" & Len(CStr(INT1.Min)) & "," & Len(CStr(INT1.Max)) & "}[.|,][0-9]{" & Len(CStr(INT2.Min)) & "," & Len(CStr(INT2.Max)) & "}"
    10. Return Match
    11. End Function

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

    Idee für Text ... Was haltet ihr davon:

    Für Texte wird eine weitere List of String erstellt, in der sich jeder Begriff einmal
    befindet (Distinct). Danach wird jedem Wort ein Vorwärs und Rückwärts-Positions
    index zugewiesen ... damit kann ich erstmal feststellen ob gewisse Worte sich immer
    an der gleichen Stelle befinden ... zudem erhält jedes Wort einen Pre-Index und einen
    After-Index, der das Voranstehende bzw. das Nachfolgende Wort erkennt. Zudem wird
    das Wort auf seine "Minimalform" gestutzt sprich ein Index für Großbuchstabe, Kleinbuchstabe,
    Zahl und Sonderzeichen vergeben, um auch Artikelnummern zu erkennen.

    Jetzt habe ich erstmal folgende Informationen:

    Wort bzw. Pattern steht immer an 1. bzw, letzter Stelle
    Wort bzw. Pattern folgt immer bzw. optional auf Wort x bzw. kommt immer nach Wort x

    jetzt kann ich schonmal anfangen das ganze von vorne und von hinten
    aufzubauen ...
    Wort 1 bzw. Wort 2 stehen nur an 1. Stelle von vorne [Wort1|Wort2]
    Wort 3 und 4 stehen immer am Ende [Wort3|Wort4]

    dann baue ich Wortgruppen auf, die immer aufeinander folgen und
    prüfe dabei, ob diese optional sind.
    Wort 5 oder 6 folgt immer auf Wort 2 wenn vorhanden ?[Wort5|Wort6]

    zum schluss werden die Wortgruppen aneinandergefügt.
    Also hätte ich dann [Wort1|Wort2]?[Wort5|Wort6][Wort3|Wort4].
    Wenn jetzt durch total wirre Texte die Unterscheidung nicht möglich ist
    kommt der Text "TO COMPLEX". Somit müsste ich zumindest für ziemlich
    gleiche Texte (bei denen u.U. was dazwischengerutscht ist) einen Pattern
    bekommen ...
    Ich kann dir nur empfehlen das Ganze sein zu lassen, ausser du hast Lust auf viele Schlaflose Nächte in denen dich Regex-Monster heimsucht. :O

    Ne Spaß bei Seite. Es wird mit jedem Zeichen dass dazu kommt komplexer. Jeder neue Fall bringt neue Schwierigkeiten mit sich und ich bin der Meinung, dass "wir" dass nicht schaffen würden.

    Das einzige was noch realistisch bzw. realistischer wäre, wäre eine Zerlegung eines Textes in alle Bestandteile(txt2re.com/) und danach den User auswählen lassen was er will.
    Bei zwei oder drei Strings, könnte man eventuell noch durchsuchen welche Menge an Bestandteilen in beiden Texten vorkommt, aber selbst das ist ein riesen Aufwand.

    Oder du programmierst einen Regex Baukasten, mit ein paar Vorlagen. Das wäre die wohl einfachste Lösung und damit würde man am schnellsten, gute Ergebnisse erzielen.
    SWYgeW91IGNhbiByZWFkIHRoaXMsIHlvdSdyZSBhIGdlZWsgOkQ=

    Weil einfach, einfach zu einfach ist! :D
    Hi,

    die schlaflosen Nächte habe ich schon hinter mir. Ich will zumindest eine "einigermaßen" passable Lösung
    erreichen ... Hab heute wieder ranprogrammiert und du hast Recht ... Immer mehr Schwierigkeiten, die
    auf einen zukommen ... Ein Baukasten für Regex ist ganz und gar nicht so der Gedanke des Programms.
    Ich kenne auch nicht viele Nutzer die Regex beherschen :D Wenns Textmäßig zu krass wird soll dort eh stehen
    "No Pattern" oder so ... also es geht hier wirklich nur um einfache Texte und nichts hochkompliziertes ...
    Es geht hier auch wahrscheinlich weniger um Regex sondern eher um die Logik ...

    Ein kleines bischen bin ich schon weitergekommen ...

    Wenn nur 1 Text vorkommt dann regex = Text

    Wenn ich erkenne dass Zahlen verwendet werden, so prüfe ich
    die Vor- und Nachkommastellen und baue zusammen [0-9]{2,3}?[,|.][0-9]{0,2}...
    klappt einwandfrei !

    Bei Texten gehts auch vorwärts.
    Im Moment möchte ich nur die 1 Wort-Texte
    richtig darstellen (Artikelnummern, Optionen, Bestellbezeichnungen, Hyperlinks):

    Jetzt gibt es also die Variablen

    WordCountMin -> Minimale Anzahl an Wörtern
    WordcountMax -> Maximale Anzahl an Wörtern
    WordCode = z.B. Wort "Handy123 ," => "AaaaaZZZ S"

    Bei < 20 Varianten, 1 Wort z.B. 3-Stellige Optionen kann ich ja [O_1|O_2|O_3] machen ... -> OK
    Bei > 20 Varianten, 1 Wort geht G[0-9[0-9] ... kann man auch noch verfeinern ... -> OK

    Bei Artikelnummern habe ich immer eine feste Abfolge von Buchstaben + Zahlen. Hier habe ich zwar
    eine große Varianz der Wörter, aber meist nur 1 Varianz beim WortCode (also "AZZZZZZ").
    Somit kann ich hier auch auflösen in M0123[4|5][2-7][1-9]. -> OK

    Das deckt schon 70 % von meinen Wünschen ab ... der weitere Fall beschäftigt sich mit 3-4 Wörtern,
    bei denen ein Buchstabe dazwischen bzw. davorrutscht ... das wird noch eine harte Nuss ... aber nicht
    unlösbar ... Wort1 und Wort4 sind immer das gleiche, Wort2 enthält eine größe Varianz, jedoch immer den
    gleichen WordCode und Wort 3 rutscht dazwischen und ist auch immer gleich ... WortCode hat jedoch nur
    2 Varianten ... und da will ich ansetzen ... mit dem WortCode kann ich dann errechnen wo einer "dazwischenrutscht"
    und den WortCode wieder in das Wort umwandeln ... ich hoffe ich stelle mir das nicht zu einfach vor ...

    ich frag mich immer wieder wie der Mensch sowas packt ... is ja ne enorme Leistung die das Gehirn da ohne
    Alorythmus errechnet ...
    Wenn mir was einfällt kann ich es dir ja posten, aber ich glaub nicht dass das so einfach wird, da du nicht nur pattern hast, sondern auch genaue zeichenabfolgen. das pattern kann sich über ein, zwei oder mehr zeichen ziehen.

    Aber wenn du etwas schreibst, würde es mich sehr interessieren.

    Zur Theorie hätte ich noch eine idee.

    du könntest den Text in regexblöcke zerlegen und die größten gemeinsamen blöcke suchen und diese als suchstring anbieten. Danach machst du noch eine auswahl ob explizit nach zeichen gesucht werden soll, die sich unterscheiden, gesucht wird oder ob ein beliebiges zeichen an der stelle vorkommen soll.

    Dann bekommst du zumindest etwas hilfreiches heraus (wenns richtig gemacht wird). Aber von 100% richtigkeit ist man da noch jahrzehnte entfernt. Ob es richtig ist, muss immer noch der user entscheiden.

    Ach ja, ganz wichtig: Sorg dafür dass im zweifelsfall mehr gefunden wird. Somit entgehen dir zumindest keine ergebnisse.
    SWYgeW91IGNhbiByZWFkIHRoaXMsIHlvdSdyZSBhIGdlZWsgOkQ=

    Weil einfach, einfach zu einfach ist! :D
    Servus,

    hier mal das Projekt ...
    docs.google.com/open?id=0B-5Myc7jmiBcRDZZYnlTdlF4bzQ

    Die Funktion Regex2 erwartet ein String(), was rauskommen soll ist ein Regex .. :)

    Das mit dem WordCode muss ich wohl noch ein bischen besser implementieren ...

    Mit den Ideen schauts mittlerweile gar nicht so schlecht aus ... das mit dem WordCode
    macht einen guten Job ... vielleicht arbeite ich auch noch ein Pre- und ein Post-Wort
    ein ... damit kann ich dann auch das optionale folgen auf ein Wort erkennen ...

    Ich muss aber auch dazusagen dass so wie es jetzt ist schon 90% von meinen Wünschen
    erfüllt ist ... zumindest mit den Tabellen, mit denen ich arbeiten muss ...
    Vielleicht fällt dir ja an der ein oder anderen Stelle (oder alles :D) eine Verbesserung ein ...

    Ich nehme zum testen privat eine Tabelle von hier her ... (erster Test Zuhause) ... Da sind noch
    einige Bugs drin, die mir erst mit dieser Tabelle aufgefallen sind ... also nicht wundern ...
    Das konzept ist zumindest schon erkennbar :D

    Ich würd mir ne Listview aufbauen, dann jede Spalte als String () an die Funktion übergeben ...
    Vielleicht bastel ich dazu noch was ... Hier die Seite:
    asciizeichen.de/tabelle.html

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

    Hab noch was für dich:

    codeproject.com/Articles/7664/StringTokenizer


    VB.NET-Quellcode

    1. Module MainProgramm
    2. Sub Main()
    3. Dim rt As New RegexToken
    4. rt.tokenize("Name23test")
    5. For Each t As Ader.Text.Token In rt
    6. Console.WriteLine(t.Kind.ToString & ": " & t.Value)
    7. Next
    8. Console.ReadLine()
    9. End Sub
    10. End Module
    11. Class RegexToken
    12. Inherits List(Of Ader.Text.Token)
    13. Sub tokenize(ByVal s As String)
    14. Dim tokenizer As New Ader.Text.StringTokenizer(s)
    15. tokenizer.SymbolChars = {","c, ":"c}
    16. MyBase.Clear()
    17. Dim tok As Ader.Text.Token
    18. Do
    19. tok = tokenizer.Next()
    20. If tok.Kind <> Ader.Text.TokenKind.EOF Then
    21. MyBase.Add(tok)
    22. End If
    23. Loop Until tok.Kind = Ader.Text.TokenKind.EOF
    24. End Sub
    25. End Class


    Ausgabe sieht so aus:
    SWYgeW91IGNhbiByZWFkIHRoaXMsIHlvdSdyZSBhIGdlZWsgOkQ=

    Weil einfach, einfach zu einfach ist! :D

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

    Hallo,

    der Source der hat schon was ... Nur dann stimmt mein Pattern nicht mehr :(
    Würde auch das gleiche Ergebnis bekommen wenn ich mir aus dem String Test123!
    den WordCode mache und dann nach "tz" und "TS" bzw. "Zz" splitte ...

    die Idee mit den Zusammenhängenden Texten ist echt gut ... wenn ich mir das Wordarray
    nehme und jedes Wort mit jedem Verknüpfe dann weiß ich ob dieser Fall immer vorkommt
    vorausgesetzt er kommt überhaupt vor ... dann wäre das Pattern eben ?[Wort1 Wort2] ...
    dann hab ich schon weniger Dinge zu vergleichen wenn ich erstmal die gleichen Pattern habe...

    Dann ist das ganze Vergleichen schon wieder um einen Schritt einfacher ...
    mhmmm ... sitz gerade irgendwie aufm schlauch ... wie schaffe ich es am sinnvollsten aus einer
    liste einzelner Wörter List (of string) eine Liste der Wörter zu machen, die immer in kombination
    auftreten ... das ganze muss so lange laufen bis keine neuen Wortkombis mehr gefunden wurden ...

    Was habe ich:

    - eine Satzliste
    - eine Wortliste
    - Eine Funktion, die mir das nachfolgende Wort ausgibt ...

    jetzt füge ich alle kombis die ich finde in eine neu Liste ein, wenn die
    Liste 1 Satz hat dann "oleole" ist es entweder nur das gesuchte wort oder
    eine kombi die immer auftritt ... bei > 1 gibts zu dem Wort mehrere kombis also
    nur wieder Wort alleine ausgeben ...

    so und jetzt die schwierigkeit ... das gefundene 2. Wort (wenn nur 1 Vorhanden ist)
    muss aus der Grundliste entfernt werden (die sich gerade in der Iteration befindet ... )
    zudem muss die Liste nach jedem Fund neu starten, um die neue Kombi mit anderen
    Worten zu vergleichen, um wirklich ein sauberes Ergebnis zu bekommen ...

    Was will ich praktisch ... Eine Funktion, der ich eine Wort- und eine Satzliste übergebe (als list of string)
    und als ergebnis erhalte ich die List of String mit den gefilterten Beiträgen zurück ...

    Satzliste:
    Das ist ein Test
    Das ist ein Test

    Wortliste:
    Das
    ist
    ein
    Test

    Ergebnis müsste sein
    Das ist ein Test

    wenn ich jetzt aber aus einem Test ein "Fest" mache
    muss ich 3 Einträge bekommen:

    - Das ist ein
    - Test
    - Fest

    Irgendwer einen Plan wie ich das anstellen könnte ? ?(
    Nimm beispielweise einen Tokenizer.

    Zuerst müsstest du den Satz in seine Einzelteile zerlegen und danach alle Token an erster Stelle vergleichen, danach alle an zweiter Stelle usw...


    Hier die benötigten Klassen:

    VB.NET-Quellcode

    1. Namespace WordToken
    2. Class Tokenizer
    3. Public Shared Function tokenize(ByVal s As String, Optional ByVal IgnoreWhiteSpace As Boolean = True) As List(Of Ader.Text.Token)
    4. Dim tokenizer As New Ader.Text.StringTokenizer(s)
    5. tokenizer.SymbolChars = {","c, ":"c}
    6. tokenizer.IgnoreWhiteSpace = IgnoreWhiteSpace
    7. Dim retval As New List(Of Ader.Text.Token)
    8. Dim tok As Ader.Text.Token
    9. Do
    10. tok = tokenizer.Next()
    11. If tok.Kind <> Ader.Text.TokenKind.EOF Then
    12. retval.Add(tok)
    13. End If
    14. Loop Until tok.Kind = Ader.Text.TokenKind.EOF
    15. Return retval
    16. End Function
    17. End Class
    18. Public Class TokenList
    19. Inherits List(Of iToken)
    20. Public Interface iToken
    21. ReadOnly Property IsMain As Boolean
    22. End Interface
    23. Public Class Token
    24. Implements iToken
    25. Public Property Storage As Ader.Text.Token
    26. Public ReadOnly Property IsMain As Boolean Implements iToken.IsMain
    27. Get
    28. Return True
    29. End Get
    30. End Property
    31. End Class
    32. Public Class SubToken
    33. Implements iToken
    34. Public Property Storage As New List(Of Ader.Text.Token)
    35. Public ReadOnly Property IsMain As Boolean Implements iToken.IsMain
    36. Get
    37. Return False
    38. End Get
    39. End Property
    40. End Class
    41. End Class
    42. End Namespace



    Hier ein Beispielaufruf:

    VB.NET-Quellcode

    1. Sub main()
    2. Dim ersterSatz As String = "Das ist ein Test"
    3. Dim zweiterSatz As String = "Das ist ein Fest"
    4. Console.WriteLine("Enter = Default (" & Chr(34) & "Das ist ein Test" & Chr(34) & ")")
    5. Console.Write("Erster Satz: ")
    6. Dim tmp As String = Console.ReadLine
    7. If Not String.IsNullOrWhiteSpace(tmp) Then ersterSatz = tmp
    8. tmp = String.Empty
    9. Console.WriteLine("")
    10. Console.WriteLine("Enter = Default (" & Chr(34) & "Das ist ein Fest" & Chr(34) & ")")
    11. Console.Write("Zweiter Satz: ")
    12. tmp = Console.ReadLine
    13. If Not String.IsNullOrWhiteSpace(tmp) Then zweiterSatz = tmp
    14. Dim l1 As List(Of Ader.Text.Token) = WordToken.Tokenizer.tokenize(ersterSatz)
    15. Dim l2 As List(Of Ader.Text.Token) = WordToken.Tokenizer.tokenize(zweiterSatz)
    16. Dim tl As New WordToken.TokenList
    17. For i As Integer = 0 To l1.Count - 1
    18. If l1(i).Value = l2(i).Value Then
    19. tl.Add(New WordToken.TokenList.Token With {.Storage = l1(i)})
    20. Else
    21. tl.Add(New WordToken.TokenList.SubToken With {.Storage = {l1(i), l2(i)}.ToList})
    22. End If
    23. Next
    24. For Each tok As WordToken.TokenList.iToken In tl
    25. If tok.IsMain Then
    26. Console.WriteLine(DirectCast(tok, WordToken.TokenList.Token).Storage.Value)
    27. Else
    28. Console.Write(":")
    29. For Each t As Ader.Text.Token In DirectCast(tok, WordToken.TokenList.SubToken).Storage
    30. Console.Write(t.Value & ":")
    31. Next
    32. Console.Write(vbCrLf)
    33. End If
    34. Next
    35. Console.ReadLine()
    36. end sub


    :)
    SWYgeW91IGNhbiByZWFkIHRoaXMsIHlvdSdyZSBhIGdlZWsgOkQ=

    Weil einfach, einfach zu einfach ist! :D
    Servus :)

    also jetzt funktioniert das ganze so wie ich es mir (bis jetzt) vorstelle ...

    läuft jetzt folgendermaßen:

    - ich lade die Liste der Sätze in die Satzliste
    - Die Sätze werden in einzelne Wörter zerlegt
    - Die Wörter werden wieder zusammengefügt wenn beide Wörter nur in dieser Kombi auftreten
    ( Vorwärtssuche Wort - Distinct = 1 + Rückwärtssuche Zielwort Distinct = 1 + ZielWort <> Wort am Sattzanfang)
    - Das ganze mache ich solange bis alle Kombinationen gefunden wurden (um mehrere Wörter zusammenzuhängen).

    - Dann nehme ich das erste Wort (bzw. die erste Wortkombi) und prüfe ob diese an der ersten Stelle immer vorkommt
    ( Für die Forward-List ) und lösche das Wort aus den Sätzen
    - Das gleiche Vorgehen mit den letzten Wörtern für die LastList

    ... Während dieser Überprüfungen wird für jeden Part eine Flatlist (TTZZZZZ ... ) generiert, um Artikelnummern zu erkennen ...
    ... Wenn ein Pattern der Wörter erkannt wurde, so wird das Wort über die Kombinatorik aufgelöst)

    - Zuletzt kommt noch die MiddleList, die alle Restlichen (wirren) Kombinationen abdeckt ...

    Dieses Vorgehen ist teilweise (bezogen auf die komplexität der Texte und Anzahl der Datensätze) sehr langsam,
    funktioniert aber bei den unterschiedlichsten Wortkombinationen schon erstaunlich gut ...

    Ausnahmen bestätigen leider immer die Regel ... Wenn die Wortkombinatorik zu krass wird, so kommt nur Shit raus ...
    Dann soll dass Programm aber auch nichts Verarbeiten ... Mit der Zeit werde ich immer mehr Sonderfälle entdecken
    und diese (soweit wie Möglich) entweder mit .*? Kennzeichnen oder das ganze Verfahren verbessern.

    Was noch fehlt ... Regex komprimieren als Extra Funktion ... bedeutet:
    ein (A|B|C|D) soll von der Funktion als (A-Z) ausgegeben werden ...
    Bei Zahlen das gleiche ... (Zahlen haben wenn es ausschließlich Zahlen sind
    bereits dieses Format) ...

    Über weitere Ideen und Verbesserungsvorschläge würde ich mich sehr freuen ...
    Danke an alle, die mir geholfen haben ...