Autor Beitrag
imoenvia
Hält's aus hier
Beiträge: 6



BeitragVerfasst: Fr 09.12.11 10:45 
Guten Morgen allerseids,

Ich habe folgendes Problem welches mich nun seit Tagen beschäftigt:

Setup:

Black und White Liste von Wörtern werden aus Datenbank geladen.
HTML Text soll beim öffnen Anhand der Listen modifiziert werden so, das
Bestimmte Wörter Markiert werden andere jedoch nicht.. zb:
teilen soll markiert werden jedoch mitteilen wo auch teilen vorkommt, soll nicht markiert werden.

Ich habe es mit RegExp probiert und das ganze sah dann so aus:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
foreach (String sp in phrasenListePositiv)
            {
                foreach (String sn in phrasenListeNegativ)
                {
                    Regex suchBegriffRegEx = new Regex(@"(^|\s)(?!" + sn + ")(" + sp + ")+$?",
                       RegexOptions.Compiled | RegexOptions.IgnoreCase);


                    result = suchBegriffRegEx.Replace(result, "<b><font style='background-color:red; color=yellow;'>" + sp + "</font></b>");
                }
            }


Es funktioniert soweit auch, jedoch ist bei der Variante das Problem, das
bei 70 Negativ Wörtern und 40 Positiv, ein Durchlauf fast 30 Sekunden benötigt.

Ich denke es gibt sicher effektivere Möglichkeiten, jedoch seh ich den Wald vor lauter
Bäumen nicht. Ich hoffe jemand kann mir auf den richtigen Pfad helfen.

Liebe Grüße und einen schönen Freitag Morgen,
Imoen, das neue C# Forum Mitglied :)
mats74
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 189
Erhaltene Danke: 26

Win 10
VS 2017/19, C++, C#
BeitragVerfasst: Fr 09.12.11 11:40 
Hallo imoenvia und :welcome:

Durch die geschachtelten foreach-Schleifen potenzierst Du deinen Prozess.
Also für jedes Positive Wort wird die gesammte Liste der negativen Wörter durchgewühlt und entsprechend formatiert.
Wenn also kein Zusammenhang der beiden Listen besteht (ist leider nicht ersichtlich), kannst Du die Listen in eine Liste zusammenfassen und nur eine foreach-Schleife durchlaufen.
Dadurch wird dein Vorgang deutlich performanter.

_________________
Gruss
mats74
imoenvia Threadstarter
Hält's aus hier
Beiträge: 6



BeitragVerfasst: Fr 09.12.11 11:51 
Danke dir für das Welcome :)

Die beiden Schleifen sind wirklich nicht das was ich will.. Problem ist halt das er wie geschrieben z.b teilen finden soll jedoch
"mitteilen" soll er ignorieren, daher bin ich davon ausgegangen das der weg mit den beiden Schleifen die Lösung wäre
mats74
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 189
Erhaltene Danke: 26

Win 10
VS 2017/19, C++, C#
BeitragVerfasst: Fr 09.12.11 12:14 
... würde eine so einfache Struktur denn den Zweck auch erfüllen:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
List<string> liste1 = new List<string>(4);
liste1.Add("Hallo");
liste1.Add("Hallo1");
liste1.Add("Hallo2");
liste1.Add("Hallo3");
foreach (String sp in liste1)
{
   if (sp.ToString() == "Hallo")
   {
      // mach was!
   }
}

Damit hast Du definitiv keine Performanceprobleme.

_________________
Gruss
mats74
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Fr 09.12.11 12:19 
Ich würde anders ansetzen.

Erstens den Html Text tokenizen(in seine Einzelteile zerlegen). Ich vermute mal du willst auch das Wort "teilen" ignorieren wenn es Teil eines Attributs oder Tags ist (Versuch mal das Wort "Background" zu highlighten ;) ). Das ist mit einem simplen Regex Replace nur schwer hinzubekommen. Ich würde also eine for Schleife über die Chars des Html Text basteln. Dann nach von dir noch zu bestimmenden Kriterien einzelne Tokens erkennen und in eine Liste schreiben. Jede Listen Position wäre dann das Token und ein Vektor mit den Postionen im Text wo das Token gefunden würde. Danach kannst du dann deine Positiv/Negativ Liste auf diese Token Liste anwenden und gegebenfalls ein Highlighting des Tokens an den gemerkten Position durchführen. Sollte, da es kein Regex und keine geschachtelten Schleifen gibt, rasend schnell sein.
imoenvia Threadstarter
Hält's aus hier
Beiträge: 6



BeitragVerfasst: Fr 09.12.11 14:01 
Danke Euch beiden erstmal für die Tipps.

Ich finde für ein Paar Suchebgriffe gleich die ganze Seite in Tokens zerlegen ist aufwändig aber ich werd es
mal versuchen. Hab zwar davon schon einmal gehört aber keine Ahnung wo ich anfangen muss ^^ Aber ich denke das wird schon :)
Yogu
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: Fr 09.12.11 17:48 
Hallo,

in deinem ersten Code gehst du die Negativ-Liste für den ganzen Text durch, auch wenn der gesuchte Positiv-Begriff gar nicht gefunden wurde. Wenn du nun viele Begriffe hast, von denen viele oft gar nicht vorkommen, ist es vielleicht besser, erst zu schauen, ob der Begriff überhaupt vorkommt (mit einem Regex-Match), und wenn ja, die innere Schleife durchlaufen. So sparst du dir für jeden nicht gefundenen Begriff so viele Regex-Replaces, wie die Negativ-Liste Einträge hat.

Grüße,
Yogu

Für diesen Beitrag haben gedankt: imoenvia
imoenvia Threadstarter
Hält's aus hier
Beiträge: 6



BeitragVerfasst: Mo 12.12.11 10:31 
Guten Morgen,

Neue Woche neues Glück :) Danke dir Yogu für den Tipp. Ich werde es abändern.