HTML parsen mit Regulären Ausdrücken

Ortwin1st

Mitglied
Hallo,

habe bereits mit contenteditable DIV's erstellt, in denen sich Text formatieren lässt. Nun würde ich gerne dafür Text parsen, um zu wissen, wie der markierte Text formatiert ist.

HTML:
document.onmouseup=txtParse;

function txtParse()
{
    var range="";
    var value = "<b>";
    var flags = "gi";
    var regExp = new RegExp(value,flags);
    //var regExp = /und (\w*)/gi;
    var result = 0;
    
    if(typeof document.selection!="undefined") {
        
        // Ausgewählten HTML-Text merken
        range=document.selection.createRange().htmlText;
        
        // Text parsen
        test="";
        while (result = regExp.exec(range)) // Solange Ergebnisse vorhanden
        {
            test += "\n    - " + result[1];
        }
        
        // Eigenschaften finden
        
        
        // Symbole markieren
        
    }    
    
    document.getElementById("output").value =
        "Ergebnis: "+result+"\n"+
        "\nErgebnis: "+test+"\n"+
        "\n$1: "+regExp.$1+
        "\n$2: "+regExp.$2+
        "\n$3: "+regExp.$3+
        "\n$4: "+regExp.$4+
        "\n$5: "+regExp.$5;
}

Denke Reguläre Ausdrücke sind zur Realisierung am Besten dafür geeignet. Habe damit aber noch nichts gemacht und finde das ein relativ schwieriges Thema. Hab mir schon diverse Referenzen hier und hier angeschaut, bin aber wenig daraus schlau geworden.

Wie könnte am Besten das Konzept aussehen, aus dem markierten String alle Eigenschaften wie <a>, <b>, <i>, <u>, <font color="..." size="..." face="..."> und <p align="..."> zu parsen?
 
Moin,

angesichts der Tatsache, dass Firefox mittlerweile arge Probleme mit RegExp-Referenzen hat, wenn bestimmte AddOns benutzt werden, kann ich bis auf Weiteres erstmal nur empfehlen, komplett auf diese zu Verzichten :-)

Ich glaube, mit dem DOM kommst du da eh besser voran.:)
Erzeuge irgendeinen Elementknoten, und weise den "Text" dessen innerHTML-Eigenschaft zu. Das erspart dir die ganze Parserei mit dem ungeliebten RegExp....untersuche die Knoten stattdessen einfach mittels der DOM-Methoden.
 
Das Script findet nur für den IE Verwendung. Das Problem bei der Lösung mit dem HTML-parsen ist, dass wenn die Benutzerselektierung (also der range-Objekt-Inhalt) keine HTML-Tags beinhaltet, das Script ziemlich blöd dastehen würde. Das kann vorkommen, wenn nur ein Teil von einem Fett markierten Text markiert werden würde.

Die DOM-Lösung hört sich besser an. Mir ist aber nur nicht klar, wie ich vom range-Objekt auf die DOM gelange?
So funktioniert das nicht wirklich:
Code:
range=document.selection.createRange();

formatTag=range.parentElement.tagName; // Rückgabewert ist 'undefined'
// oder
formatTag=range.parentNode.tagName; // erzeugt Fehlermeldung
 
Zuletzt bearbeitet:
Wenn es nur für den IE sein soll, dann bietet dieser eine Reihe praktischer Werkzeuge, z.B. jene: :)

Code:
RangeObject.htmlText//liefert die HTML-Source der Auswahl
RangeObject.parentElement()//liefert den Elternknoten der Auswahl
 
Ups, hab die Klammer vergessen. :rolleyes:
RangeObject.parentElement();
Deshalb hat's mit dem tagName nicht geklappt.

Muss dann mal ausprobieren, ob und wie ich es hinkrieg.

Konzept:
Werde solange mit parentElement durchgehen, bis ich alle Tags habe. Wenn parentElement().tagName==div (noch sicherer ID überprüfen), dann hab ich alle Elemente durch. Dann nur noch sortieren und den Formatsymbolen zuordnen.
So sollte es ungefähr gehen.
 
So, hab da mal was geschrieben, was hier hereinstellen möchte.

Der HTML-Teil:
HTML:
  <table id="tlbForm" style="margin:1px;border:0;border-collapse:collapse;border-spacing:0">
    <tr>
      <td>
        <span class="tdTlB" style="background:#F22;color:#FFF"
          onmouseover="this.className='cmdOvr'" onmouseout="this.className='tdTlB'"
          onmousedown="this.className='cmdDwn'" onmouseup="this.className='cmdOvr'" 
          onclick="editQuit()" title="Bearbeitungsmodus beenden">&nbsp;<b>&times;</b>
        </span>
      </td>
      <td colspan="9">
        <select id="fntClr" style="width:39%" title="Schriftfarbe"
            onChange="txtFrm('ForeColor', this.options[this.selectedIndex].style.color);">
          <option style="color:black">Schwarz</option>
          <option style="color:gray">Grau</option>
          <option style="color:silver">Silber</option>
          <option style="color:white">Wei&szlig;</option>
          <option style="color:red">Rot</option>
          <option style="color:maroon">Dunkelrot</option>
          <option style="color:orange">Orange</option>
          <option style="color:yellow">Gelb</option>
          <option style="color:olive">Dunkelgelb</option>
          <option style="color:lime">Hellgr&uuml;n</option>
          <option style="color:green">Gr&uuml;n</option>
          <option style="color:aqua">T&uuml;rkis</option>
          <option style="color:teal">Blaugr&uuml;n</option>
          <option style="color:blue">Blau</option>
          <option style="color:navy">Dunkelblau</option>
          <option style="color:fuchsia">Pink</option>
          <option style="color:purple">Lila</option>
        </select><select id="fntFce" style="width:42%" title="Schriftart"
            onchange="txtFrm('FontName', this.options[this.selectedIndex].innerText);">
          <option title="Arial">Arial</option>
          <option title="Comic Sans MS">Comic Sans MS</option>
          <option title="Courier New">Courier New</option>
          <option title="Fixedsys">Fixedsys</option>
          <option title="Georgia">Georgia</option>
          <option title="Helvetica">Helvetica</option>
          <option title="Impact">Impact</option>
          <option title="Tahoma">Tahoma</option>
          <option title="Times New Roman">Times New Roman</option>
          <option title="Trebuchet MS">Trebuchet MS</option>
          <option title="Verdana">Verdana</option>
        </select><select id="fntSze" style="width:19%" title="Schriftgr&ouml;&szlig;e"
            onChange="txtFrm('FontSize', this.options[this.selectedIndex].innerText);">
          <option>1</option>
          <option selected>2</option>
          <option>3</option>
          <option>4</option>
          <option>5</option>
          <option>6</option>
          <option>7</option>
        </select>
      </td>
      <td>
        <button class="tdTlB" onmouseover="this.className='cmdOvr'" onmouseout="this.className='tdTlB'"
          onmousedown="this.className='cmdDwn'" onmouseup="this.className='cmdOvr'" 
          onclick="txtFrm('FontSizeRel','-1')"
          title="Kleiner">a-
        </button>
      </td>
      <td>
        <button class="tdTlB" onmouseover="this.className='cmdOvr'" onmouseout="this.className='tdTlB'"
          onmousedown="this.className='cmdDwn'" onmouseup="this.className='cmdOvr'" 
          onclick="txtFrm('FontSizeRel','+1')"
          title="Gr&ouml;&szlig;er">a+
        </button>
      </td>
    </tr>
    <tr>
      <td>
        <button class="tdTlB" onmouseover="this.className='cmdOvr'" onmouseout="this.className='tdTlB'"
          onmousedown="this.className='cmdDwn'" onmouseup="this.className='cmdOvr'" 
          onclick="txtFrm('BR')"
          title="Zeilenumbruch"><font face="Symbol">¿</font><!--&crarr;-->
        </button>
      </td>
      <td>
        <button class="tdTlB" onmouseover="this.className='cmdOvr'" onmouseout="this.className='tdTlB'"
          onmousedown="this.className='cmdDwn'" onmouseup="this.className='cmdOvr'" 
          onclick="txtFrm('P')"
          title="Absatz">&para;
        </button>
      </td>
      <td>
        <button class="tdTlB" onmouseover="this.className='cmdOvr'" onmouseout="this.className='tdTlB'"
          onmousedown="this.className='cmdDwn'" onmouseup="this.className='cmdOvr'" 
          onclick="txtFrm('HR')"
          title="Trennlinie">&mdash;
        </button>
      </td>
      <td>
        <button class="tdTlB" onmouseover="this.className='cmdOvr'" onmouseout="this.className='tdTlB'"
          onmousedown="this.className='cmdDwn'" onmouseup="this.className='cmdOvr'" 
          onclick="txtFrm('Bold')"
          id="B" title="Fett"><b>F</b>
        </button>
      </td>
      <td>
        <button class="tdTlB" onmouseover="this.className='cmdOvr'" onmouseout="this.className='tdTlB'"
          onmousedown="this.className='cmdDwn'" onmouseup="this.className='cmdOvr'" 
          onclick="txtFrm('Italic')"
          id="I" title="Kursiv"><i>K</i>
        </button>
      </td>
      <td>
        <button class="tdTlB" onmouseover="this.className='cmdOvr'" onmouseout="this.className='tdTlB'"
          onmousedown="this.className='cmdDwn'" onmouseup="this.className='cmdOvr'" 
          onclick="txtFrm('Underline')"
          id="U" title="Unterstreichen"><u>U</u>
        </button>
      </td>
      <td>
        <button class="tdTlB" onmouseover="this.className='cmdOvr'" onmouseout="this.className='tdTlB'"
          onmousedown="this.className='cmdDwn'" onmouseup="this.className='cmdOvr'" 
          onclick="txtFrm('CreateLink','',true)"
          id="A" title="Hyperlink"><u style="color:blue">H</u>
        </button>
      </td>
      <td>
        <button class="tdTlB" onmouseover="this.className='cmdOvr'" onmouseout="this.className='tdTlB'"
          onmousedown="this.className='cmdDwn'" onmouseup="this.className='cmdOvr'" 
          onclick="txtFrm('JustifyLeft')"
          id="left" title="Linksb&uuml;ndig"><font face="Symbol">Ü</font><!--&rarr;-->
        </button>
      </td>
      <td>
        <button class="tdTlB" onmouseover="this.className='cmdOvr'" onmouseout="this.className='tdTlB'"
          onmousedown="this.className='cmdDwn'" onmouseup="this.className='cmdOvr'" 
          onclick="txtFrm('JustifyCenter')"
          id="center" title="Zentriert"><font face="Symbol">Û</font><!--&harr;-->
        </button>
      </td>
      <td>
        <button class="tdTlB" onmouseover="this.className='cmdOvr'" onmouseout="this.className='tdTlB'"
          onmousedown="this.className='cmdDwn'" onmouseup="this.className='cmdOvr'" 
          onclick="txtFrm('JustifyRight')"
          id="right" title="Rechtsb&uuml;ndig"><font face="Symbol">Þ</font><!--&larr;-->
        </button>
      </td>
      <td>
        <button class="tdTlB" onmouseover="this.className='cmdOvr'" onmouseout="this.className='tdTlB'"
          onmousedown="this.className='cmdDwn'" onmouseup="this.className='cmdOvr'" 
          onclick="txtFrm('InsertUnorderedList')"
          id="UL" title="Ungeordnete Liste">UL
        </button>
      </td>
      <td>
        <button class="tdTlB" onmouseover="this.className='cmdOvr'" onmouseout="this.className='tdTlB'"
          onmousedown="this.className='cmdDwn'" onmouseup="this.className='cmdOvr'" 
          onclick="txtFrm('InsertOrderedList')"
          id="OL" title="Geordnete Liste">OL
        </button>
      </td>
    </tr>
  </table>

Der JavaScript bzw. JScript-Teil:
Code:
function txtParse()
{
    var range="", i=0, j=0;
    var curTag, aryTag= new Array();
    //var regExp = new RegExp(".e","i"), result = 0;
    var fntFace = document.getElementById("fntFce");
    var fntColor = document.getElementById("fntClr");
    
    if(txtObj) {        
        if(typeof document.selection!="undefined") {
            txtObj.focus(); 
            
            // Ausgewählten Text merken
            range=document.selection.createRange();
            
            curTag=range.parentElement();            
            // Solange noch im DIV
            while(curTag.id != "foo") 
            {
                // Wenn nicht mehr DIV
                if(curTag.tagName=="BODY") break;
                
                // Jedes Tag in Array
                aryTag[i]=curTag; //.tagName+", "+i;
                
                // Nächthöheres Element
                curTag=curTag.parentElement;
                
                i++;
            }
            
            // Eigenschaften zurücksetzen
            document.getElementById("B").className="tdTlB";
            document.getElementById("I").className="tdTlB";
            document.getElementById("U").className="tdTlB";
            document.getElementById("A").className="tdTlB";
            document.getElementById("center").className="tdTlB";
            document.getElementById("right").className="tdTlB";
            fntColor.options[0].selected="true";
            fntFace.options[0].selected="true";
            document.getElementById("fntSze").options[1].selected="true";
            
            // Symbole markieren
            while(i>0)
            {
                i--;
                switch(aryTag[i].tagName)
                {
                    case "B", "STRONG":
                        document.getElementById("B").className="cmdDwn";
                        break;
                    case "I", "EM":
                        document.getElementById("I").className="cmdDwn";
                        break;
                    case "U":
                        document.getElementById("U").className="cmdDwn";
                        break;
                    case "A":
                        document.getElementById("A").className="cmdDwn";
                        break;
                    case "UL":
                        document.getElementById("UL").className="cmdDwn";
                        break;
                    case "OL":
                        document.getElementById("OL").className="cmdDwn";
                        break;
                    case "P":
                        document.getElementById("left").className="tdTlB";
                        document.getElementById(aryTag[i].align).className="cmdDwn";
                        break;
                    case "FONT":
                        if(aryTag[i].color) {
                            for(j=0;j<fntColor.length;j++) 
                            {
                                if(fntColor.options[j].style.color==aryTag[i].color)
                                    fntColor.options[j].selected="true";
                            }
                        }
                        if(aryTag[i].face!="") { // Schriftart wählen
                            for(j=0;j<fntFace.length;j++) 
                            {
                                if(fntFace.options[j].innerText==aryTag[i].face)
                                    fntFace.options[j].selected="true";
                            }
                        }
                        if(aryTag[i].size) { // Größe von 1 bis 7 wählen
                            document.getElementById("fntSze").options[aryTag[i].size-1].selected="true";
                        }
                        break;
                }
            }            
        }
    }
}

Könnten noch ein paar Bugs drinnen sein, die ich rausbügeln müsste.
Blöd ist, dass "color" den HEX-Wert zurückgibt und nicht den zugewiesenen Farbnamen. Wahrscheinlich, weil ich im nachhinein das bereits gerenderte HTML einlese und nicht das, was die Seite bzw. den Text beschreibt.

Was gibt's dazu noch zu sagen... fällt mir nix mehr ein.
 
Zuletzt bearbeitet:

Neue Beiträge

Zurück