RegEx - langsam

  • C#
  • .NET (FX) 4.5–4.8

Es gibt 14 Antworten in diesem Thema. Der letzte Beitrag () ist von Corby.

    RegEx - langsam

    Hallo,
    ich möchte mithilfe RegEx auf dieser Webseite Filme und das jeweilige Genre auslesen.

    HTML-Quellcode

    1. <h3 itemprop="name" class="bold epg-col-broadcast-hover-12037221">
    2. Um Himmels Willen </h3>
    3. <div class="small-font">
    4. <span itemprop="genre">Familienserie</span>


    Mein Versuch mit diesem Pattern:

    bold.+\\s+(?<Film>.+)</h3>\\s+.+\\s+.+genre\">(?<Genre>.+)<

    Es funktioniert, aber es ist erstens langsam und zweitens gibt es bestimmt eine schönere/bessere Lösung.

    Könnt ihr mir helfen?

    MfG Corby :)
    Star mich nicht so an, ich bin auch nur eine Signatur
    Danke für eure Antworten. Ich hab es mal mit RegexOption.Compiled ausprobiert, hat sich aber nichts großartig verändert.

    Und evtl. ist das langsame ja garnet der Regex, sondern das laden der Website.

    Hab ich mir auch schon gedacht und deshalb den Quelltext in einen String schreiben lassen und mit RegEx extra überprüfen lassen. Braucht jedoch genauso lang.

    Ich hab das ganze mal über einen anderen (neueren) PC laufen lassen, da geht es deutlich schneller, kann also auch am PC liegen.

    Außerdem hab ich ein weiteres Problem, bei manchen Sendungen gibt es eine Empfehlung, somit funktioniert mein Pattern nicht mehr.

    HTML-Quellcode

    1. <h3 itemprop="name" class="bold epg-col-broadcast-hover-12041239">
    2. 16 über Nacht! <span class="moviestar moviestar-red moviestar-broadcast"></span>
    3. </h3>
    4. <div class="small-font">
    5. <span class="badge badge-btn badge-btn-small badge-btn-small-daytip">TAGES-TIPP</span>
    6. <span itemprop="genre">Komödie</span>


    Hat jemand eine Idee wie man das lösen könnte? Ich will nicht extra zwei Pattern haben (bold.+\\s+(?<Film>.+) und genre\">(?<Genre>.+)<).

    MfG Corby :)
    Star mich nicht so an, ich bin auch nur eine Signatur
    Das Problem (die Geschwindigkeit) könnte aber auch in deinem Code liegen, poste die entsprechende Methode einfach mal.
    Das Problem (die Geschwindigkeit) könnte aber auch in deinem Code liegen, poste die entsprechende Methode einfach mal.


    RegEx:

    C#-Quellcode

    1. Regex FilmPatter = new Regex("bold.+\\s+(?<Film>.+)</h3>\\s+.+\\s+.+genre\">(?<Genre>.+)<");
    2. MatchCollection FilmMatches = FilmPatter.Matches(htmlsource);


    WebRequest:

    C#-Quellcode

    1. WebRequest request = WebRequest.Create(URL);
    2. WebResponse response = request.GetResponse();
    3. StreamReader reader = new StreamReader(response.GetResponseStream());
    4. string htmlsource = reader.ReadToEnd();


    Ich glaube aber nicht, dass es daran liegt...

    @simpleSoft
    Wow wusste gar nichts davon. Sieht echt einfacher zum auswerten aus, werde ich später versuchen. Danke!

    MfG Corby :)
    Star mich nicht so an, ich bin auch nur eine Signatur
    Das ist ja auch nicht die gesamte Methode sondern nur einzelne Zeilen Code. Es geht um den Kontext in dem der Code läuft (iwelche Schleifen, mehrfach aufrufen etc.) und deswegen meinte ich das du die Methode posten solltest.
    Sry, hier die ganze Methode:

    C#-Quellcode

    1. public void Auslesen()
    2. {
    3. WebRequest request = WebRequest.Create(URL);
    4. WebResponse response = request.GetResponse();
    5. StreamReader reader = new StreamReader(response.GetResponseStream());
    6. string htmlsource = reader.ReadToEnd();
    7. Regex FilmPatter = new Regex("bold.+\\s+(?<Film>.+)</h3>\\s+.+\\s+.+genre\">(?<Genre>.+)<"); // RegexOptions.Compiled
    8. MatchCollection FilmMatches = FilmPatter.Matches(htmlsource);
    9. for (int i = 0; i < 9; i++)
    10. {
    11. Filme[i] = FilmMatches[i].Groups["Film"].Value;
    12. Genre[i] = FilmMatches[i].Groups["Genre"].Value;
    13. }
    14. }


    MfG Corby :)
    Star mich nicht so an, ich bin auch nur eine Signatur

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

    Ich persönlich habe die Erfahrung gemacht, dass es bei RegEx besser ist, du erstellst eine statische Variable (oder auch Property) in der Klasse und siehst zu, dass es vor dem ganzen anderen Gedöns kompiliert wird:

    C#-Quellcode

    1. using System;
    2. namespace com.FooBar {
    3. using System.Text.RegularExpressions;
    4. public static class Foo {
    5. private static readonly Regex m_webRegex;
    6. public static Regex WebRegex {
    7. get {
    8. return m_webRegex;
    9. }
    10. }
    11. static Foo() {
    12. m_webRegex = new Regex("bold.+\\s+(?<Film>.+)</h3>\\s+.+\\s+.+genre\">(?<Genre>.+)<", RegexOptions.Compiled | RegexOptions.IgnoreCase);
    13. }
    14. }
    15. }
    "Nichts ist unendlich, bis auf die menschliche Dummheit" - Albert Einstein
    "Man sollte nicht alles vertrauen, was im Netz steht" - Abraham Lincoln
    und ich würd mir wünschen, dass corby mal offenlegt, wie er die Langsamkeit des Regexes nachweist.
    Etwa etwas in der Art:

    C#-Quellcode

    1. public void Auslesen()
    2. {
    3. WebRequest request = WebRequest.Create(URL);
    4. WebResponse response = request.GetResponse();
    5. StreamReader reader = new StreamReader(response.GetResponseStream());
    6. string htmlsource = reader.ReadToEnd();
    7. var sw=StopWatch.StartNew();
    8. Regex FilmPatter = new Regex("bold.+\\s+(?<Film>.+)</h3>\\s+.+\\s+.+genre\">(?<Genre>.+)<"); // RegexOptions.Compiled
    9. MatchCollection FilmMatches = FilmPatter.Matches(htmlsource);
    10. Messagebox.Show(sw.ElapsedMilliSeconds.ToString());
    11. for (int i = 0; i < 9; i++)
    12. {
    13. Filme[i] = FilmMatches[i].Groups["Film"].Value;
    14. Genre[i] = FilmMatches[i].Groups["Genre"].Value;
    15. }
    16. }
    ich vermute nämlich, dass der Webrequest vielfach langsamer ist.
    @ErfinderDesRades

    Stimmt. Daran hatte ich gar nicht gedacht.

    Aber dann würde ich zwei StopWatches nehmen und beides messen. Ggf. in ein Array speichern und dann ausgeben.

    Wobei, was mir da auch in den Sinn kommt? Wieso machst du das nicht mit Async-Await?

    C#-Quellcode

    1. public async void ReadDataAsync(Url m_Url) {
    2. await Task.Run(new Action(() => {
    3. WebRequest request = WebRequest.Create(URL);
    4. WebResponse response = request.GetResponse();
    5. StreamReader reader = new StreamReader(response.GetResponseStream());
    6. string htmlsource = reader.ReadToEnd();
    7. var sw=StopWatch.StartNew();
    8. Regex FilmPatter = new Regex("bold.+\\s+(?<Film>.+)</h3>\\s+.+\\s+.+genre\">(?<Genre>.+)<"); // RegexOptions.Compiled
    9. MatchCollection FilmMatches = FilmPatter.Matches(htmlsource);
    10. Messagebox.Show(sw.ElapsedMilliSeconds.ToString());
    11. for (int i = 0; i < 9; i++) {
    12. Filme[i] = FilmMatches[i].Groups["Film"].Value;
    13. Genre[i] = FilmMatches[i].Groups["Genre"].Value;
    14. }
    15. }));
    16. }


    Dann ist es doch relativ egal wie lange es dauert, da es sowieso asynchron läuft?
    "Nichts ist unendlich, bis auf die menschliche Dummheit" - Albert Einstein
    "Man sollte nicht alles vertrauen, was im Netz steht" - Abraham Lincoln
    ​die von simpleSoft vorgeschlagene XML Seite
    Da solltest du allerdings beachten, dass die RSS-Feeds nur einige Mal pro Tag aktualisiert werden.
    Je nach Anforderung und Feed könnte dir das evtl. nicht reichen.
    Such auf jeden Fall den von dir benötigten RSS-Feed raus und beobachte den ein paar Tage.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --