Olaf: Wie body mit regulären Ausdrcken auslesen?

Hallo,

in einem String parsef bekomme ich den kompletten Quellcode einer HTML Datei übergeben, also "<html>..bis...</html>".

Aus diesem String möchte ich mit regulären Ausdrücken jetzt den <body>..</body> herausziehen

Habe es so probiert, aber das klappt irgendwie nicht. Das Fragezeichen habe ich gesetzt, damit der erste Ausdruck
nicht gierig ist.

if(parsef.match(/(<body.+>)?(.+)(body>)/i)) {
   alert(RegExp.$1);
   alert(RegExp.$2);
   alert(RegExp.$3);
  }

Die alerts geben irgendwas aus. Ich komme einfach nicht weiter. Was mache ich falsch?

Dank & gruss

Olaf

  1. Hi,

    if(parsef.match(/(<body.+>)?(.+)(body>)/i)) {

    Du suchst also optional den String "<body", gefolgt von maximal vielen Zeichen, nach denen ein ">" steht; gefolgt von maximal vielen der verbleibenden Zeichen; gefolgt von der Zeichenkette "body>".

    Die alerts geben irgendwas aus. Ich komme einfach nicht weiter. Was mache ich falsch?

    Du hast die Bedeutung des Fragezeichens und des "+"- und vermutlich auch "*"-Operators noch nicht voll verstanden. Zudem bin ich nicht sicher, ob Du Dir der Bedeutung von Klammern wirklich bewusst ist.

    Cheatah

    --
    X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
    X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
    X-Will-Answer-Email: No
    X-Please-Search-Archive-First: Absolutely Yes
    1. Lieber Cheatah,

      Du hast die Bedeutung des Fragezeichens und des "+"- und vermutlich auch "*"-Operators noch nicht voll verstanden. Zudem bin ich nicht sicher, ob Du Dir der Bedeutung von Klammern wirklich bewusst ist.

      Na, dann helfen wir dem OP doch auf die Sprünge!

      /(body)/ findet das Vorkommen von "body" und merkt es sich in RegExp.$1. Da im öffnenden BODY-Tag Parameter enthalten sein _können_ (aber eben nicht müssen) ist der "+"-Operator hier nicht optimal, da er mindestens ein Vorkommen vorraussetzt, das hier aber nicht gegeben sein muss.

      /(<body[^>]*>)/i findet alles was mit "<body" anfängt, mit ">" aufhört, und was dazwischen beliebig viele (auch keine) Zeichen enthalten kann, die aber allesamt kein ">" sein dürfen. Die Unterscheidung zwischen Groß- und Kleinschreibung ist durch den Schalter "i" deaktiviert. Javascript merkt sich den kompletten Ausdruck in RegExp.$1.

      Der OP möchte doch nur den Code innerhalb des BODYs, also braucht er:

      var hatGeklappt = mystring.match(/<body[^>]*>(.*)<\/body>/i);  
      alert(RegExp.$1);
      

      Habe das zwar jetzt nicht ausprobiert, denke aber, dass es funzt(R).

      Liebe Grüße aus Ellwangen,

      Felix Riesterer.

      1. Hallo Felix.

        /(<body[^>]*>)/i findet alles was mit "<body" anfängt, mit ">" aufhört, und was dazwischen beliebig viele (auch keine) Zeichen enthalten kann, die aber allesamt kein ">" sein dürfen.

        Hm. Im Grunde ist dieser übliche Ausdruck überholt, da folgendes sehr wohl erlaubt ist:

        <body title="Go to the right ->">  
          <h1>Bla!</h1>  
        </body>
        

        Es müsste also auf „<body“ gefolgt von keinem oder einem beliebigen Zeichen und „>“--sofern es sich innerhalb von " oder ' befindet--beliebig oft, gefolgt von „>“ gematcht werden.

        Mein bisheriger Versuch:

        /(<body(?(["'].*>.*["'])…|[^>]*)>(.*)<\/body>)/i

        An Stelle des „…“ muss natürlich noch ein brauchbarer Ausdruck, aber mir fällt keiner ein.

        Außerdem erhalte ich sowohl in JS als auch in PHP „Compilation failed: assertion expected after (?(“.
        Habe ich die bedingten Unterausdrücke falsch verstanden?

        Einen schönen Freitag noch.

        Gruß, Ashura

        --
        sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|
        mathbr:del.icio.us/ mathbr:w00t/
        1. Lieber Ashura!

          Mein bisheriger Versuch:

          /(<body(?(["'].*>.*["'])…|[^>]*)>(.*)<\/body>)/i

          Habe ich die bedingten Unterausdrücke falsch verstanden?

          Für alternative Versionen kannst Du jederzeit /(a|b)/i schreiben. Ein Fragezeichen am Anfang einer Klammer braucht wohl noch etwas Zusätzliches, wie

          (?<!look-behind)  
          (?:forget-about-it)  
          (?!look-ahead)
          ~~~,  
            
          wobei aber Javascript kein lookbehind kennt.  
            
          Sollte ich hier Mist verzapfen, dann korrigiere mich bitte jemand!  
            
          Liebe Grüße aus [Ellwangen](http://www.ellwangen.de/),  
            
          Felix Riesterer.
          
          1. Hallo Felix.

            Für alternative Versionen kannst Du jederzeit /(a|b)/i schreiben.

            Ja, ist mir bekannt. Ich wollte aber vermeiden, dass die Anführungszeichen noch einmal extra eingefangen werden und (?:)-Spielchen vermeiden.

            Ein Fragezeichen am Anfang einer Klammer braucht wohl noch etwas Zusätzliches, wie

            Ja, damit erscheint keine Fehlermeldung mehr, aber leider auch nicht das Gewünschte.

            (?<!look-behind)

            (?:forget-about-it)
            (?!look-ahead)

            
            >   
            > wobei aber Javascript kein lookbehind kennt.  
            >   
            > Sollte ich hier Mist verzapfen, dann korrigiere mich bitte jemand!  
              
            Also kann JS [bedingte Unterausdrücke](http://pcre.nophia.de/explain/subpattern/conditional/index.php) allgemein nicht?  
              
              
            Einen schönen Freitag noch.  
              
            Gruß, Ashura  
            
            -- 
            sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|  
            [<mathbr:del.icio.us/>](http://del.icio.us/mathbr) [<mathbr:w00t/>](http://w00t.noctus.net)
            
            1. Lieber Ashura,

              Also kann JS bedingte Unterausdrücke allgemein nicht?

              es hat diesen Anschein...

              Liebe Grüße aus Ellwangen,

              Felix Riesterer.

        2. Hi,

          Mein bisheriger Versuch:
          /(<body(?(["'].*>.*["'])…|[^>]*)>(.*)<\/body>)/i
          An Stelle des „…“ muss natürlich noch ein brauchbarer Ausdruck, aber mir fällt keiner ein.

          Zur leichteren Kommentierung mal in der "Freeform"-Variante (siehe /x modifier):

          /
              <body                    #Anfangs mal ein <body
              (?:                      #die Anzahl der Attribute ist 0 bis unendlich
                  \s+                  #zwischen elementname und attributname bzw. zwischen
                  [a-z]+               #Attributname
                  (?:                  #optional hat ein Attribut auch einen Wert
                      \s*              #vor dem = darf whitespace stehen
                      =                #ein =
                      \s*              #nach dem = darf whitespace stehen
                      (?:              #Wert darf in '' oder "" stehen oder ohne Quotes
                          '[^']*'      #Wert in '', evtl. auch leer, erstes ' beendet den Wert
                      |
                          "[^"]*"      #Wert in "", evtl. auch leer, erstes " beendet den Wert
                      |
                          [-a-z0-9._]+ #ggf. auch Wert ohne Quotes [1]
                      )
                  )?
              )*
              \s*                      #vor dem > kann Whitespace stehen
              >                        #schließt das tag
              (                        #Das wollen wir uns merken!
                  .*?                  #sowenig beliebiges wie möglich
              )                        #(nur bis zum ersten (und hoffentlich einzigen) schließenden body-Tag)
              </body                   #der Anfang des schließenden body-Tags
              \s*                      #ggf. Whitespace im schließenden tag
              >                        #schließt das tag
          /ix

          [1] (keine Garantie auf Vollständigkeit der Zeichenliste, ggf. \S* , wenns invalides HTML ist)
          oder einzeilig:

          /<body(?:\s+[a-z]+(?:\s*=\s*(?:'[^']*'|"[^"]*"|[-a-z0-9._]+))?)*\s*>(.*?)</body\s*>/i

          (ohne Gewähr)

          cu,
          Andreas

          --
          Warum nennt sich Andreas hier MudGuard?
          Schreinerei Waechter
          Fachfragen per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
          1. Hallo MudGuard.

            /<body(?:\s+[a-z]+(?:\s*=\s*(?:'[^']*'|"[^"]*"|[-a-z0-9._]+))?)*\s*>(.*?)</body\s*>/i

            Dies funktioniert tatsächlich.
            (Nach dem der Slash in </body> maskiert wurde, versteht sich.)

            Einen schönen Freitag noch.

            Gruß, Ashura

            --
            sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|
            mathbr:del.icio.us/ mathbr:w00t/
            1. Hi,

              /<body(?:\s+[a-z]+(?:\s*=\s*(?:'[^']*'|"[^"]*"|[-a-z0-9._]+))?)*\s*>(.*?)</body\s*>/i
              Dies funktioniert tatsächlich.
              (Nach dem der Slash in </body> maskiert wurde, versteht sich.)

              Also nur ein minimaler Fehler - dafür, daß ich das ganze nur so auf die Schnelle aufgeschrieben hab, ist das doch nicht schlecht
              Da ich fast immer ~ als Begrenzungszeichen wähle (~ kommt fast nie in meinen Ausdrücken vor, / dagegen öfter), denk ich nicht dran, den / zu maskieren (Außerdem: mit dem Maskieren ist es doch seit Aschermittwoch eh erst mal vorbei ;-)

              cu,
              Andreas

              --
              Warum nennt sich Andreas hier MudGuard?
              Schreinerei Waechter
              Fachfragen per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
              1. Hallo MudGuard.

                Also nur ein minimaler Fehler - dafür, daß ich das ganze nur so auf die Schnelle aufgeschrieben hab, ist das doch nicht schlecht

                Definitiv.

                Da ich fast immer ~ als Begrenzungszeichen wähle (~ kommt fast nie in meinen Ausdrücken vor, / dagegen öfter), denk ich nicht dran, den / zu maskieren

                Meine Ergänzung war natürlich auch nur auf JS bezogen.
                In PHP musst du bekanntlich entweder ' oder " maskieren, je nach dem, was du als Zeichenkettenbegrenzer gewählt hast.

                (Außerdem: mit dem Maskieren ist es doch seit Aschermittwoch eh erst mal vorbei ;-)

                Äußerst erfreulich, finde ich.

                Einen schönen Samstag noch.

                Gruß, Ashura

                --
                sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|
                mathbr:del.icio.us/ mathbr:w00t/
                1. Hi,

                  In PHP musst du bekanntlich entweder ' oder " maskieren, je nach dem, was du als Zeichenkettenbegrenzer gewählt hast.

                  Ich perle in letzter Zeit relativ viel - da braucht es keine zusätzlichen Begrenzer ...

                  (Außerdem: mit dem Maskieren ist es doch seit Aschermittwoch eh erst mal vorbei ;-)
                  Äußerst erfreulich, finde ich.

                  Mir geht der Fasching ziemlich am :after vorbei (bis auf die Krapfen - das einzig brauchbare an der ganzen Sache - , die gehen nach dem Verzehr eher mittendurch).

                  cu,
                  Andreas

                  --
                  Warum nennt sich Andreas hier MudGuard?
                  Schreinerei Waechter
                  Fachfragen per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.