Problem mit RegExp
PoWl24
- javascript
Hi!
Ich bin grad dabei mir einen WYSIWYG-Editor zu basteln. Um den erzeugten HTML-Code in für mich nötigen BB-Code umzuwandeln schicke ich ihn durch eine reihe replace-befehle.
Unter anderem:
htmlcode = htmlcode.replace(/<b>(.*)</b>/gim, "[B]$1[/B]");
Wenn ich nun aber in einer Zeile <b>Bla</b>Moep<b>Blub</b> stehen hab, wird das wie folgt ersetzt: [B]Bla</b>Moep<b>Blub[/B]
gibt es irgendein flag das dem regexp befiehlt immer nur die kleinstmögliche Zeichenkette zu nehmen?
mfg PoWl
Moin!
htmlcode = htmlcode.replace(/<b>(.*?)</b>/gim, "[B]$1[/B]");
-- Skeeve
Moin!
Nachtrag: Warum machst Du nicht einfach:
htmlcode = htmlcode.replace(/<(/?b)>/gim, "[$1]");
Das kannst Du dann gleich erweitern auf:
htmlcode = htmlcode.replace(/<(/?(?:b|u|font\b[^>]*))>/gim, "[$1]");
usw...
-- Skeeve
Servus,
htmlcode = htmlcode.replace(/<b>(.*)</b>/gim, "[B]$1[/B]");
[...]
gibt es irgendein flag das dem regexp befiehlt immer nur die
kleinstmögliche Zeichenkette zu nehmen?
das Verhalten von Quantifizierern wie '*' lässt sich durch ein
angehängtes Fragezeichen umkehren - von der Voreinstellung 'gierig'
auf 'nicht gierig' - ich würde davon aber in den meisten Fällen
abraten, da es nicht besonders performant ist. Um Tags per Parser
zu erfassen benutze ich meist Abwandlungen von dieser Form:
<b[^>]+>([^<]+)</b>
In dem Fall wird das kleinstmögliche Tag-Paar gefunden.
Grüsse
Danke für die Antworten, habe das inzwischen mit dem ? gelöst, kann ich ja hinterher nochmal abändern.
Nun ergibt sich für mich ein neues Problem: Geckobrowser sind nicht besonderes intelligent was das erstellen von HTML code für die Einrückgung betrifft.
Ein Beispiel: Ich schreibe in 5 Zeilen jeweils einen Buchstabe ABCDE, dann markiere ich alle, wähle Right, dann die 3 mittleren, wähle center, und zum schluss den ganz mittleren und wähle left. Während der IE ausnahmsweise mal was gutes tut und für jede einzelne Zeile einen eigens align angibt handhabt Gecko das folgendermaßen:
<div align="right">A<br><div align="center">B<br><div align="left">C<br></div>D<br></div>E<br>
</div>
D.h. wir haben da folgendermaßen eine Verschachtelung, die Einrückung dient nur zur Übersicht
[RIGHT]A
[CENTER]B
[LEFT]C[/LEFT]
D[/CENTER]
E[/RIGHT]
So ungefär sollte das hinterher aussehen. Aber da stoß ich auf mein Problem, dadurch dass das ende immer ein </div> ist und der anfang jeweils unterschiedlich weiß mein regulärer ausdruck nicht ganz was er jetzt tun soll
das endet dann so:
[RIGHT]A
[CENTER]B
[LEFT]C[/RIGHT]
D[/CENTER]
E[/LEFT]
Lass ich ihn immer den größten String dazwischen suchen kann es wiederrum passieren dass manche Tags garnicht geparsed werden.
Theoretisch müsste ich immer versuchen die inneren Tags zuerst zu parsen und mich langsam nach aussen durchzuarbeiten, wie geht das denn? Könnte mir schon vorstellen. Immer nur einen replace durchführen mit einem regulären ausdruck der immer den innersten Tag parsed. Und den so oft ausführen wie Tags gefunden werden. Wie sähe aber ein solcher Ausdruck aus? Gibt es eine Bessere möglichkeit?
mfg PoWl
Moin!
Wie sähe aber ein solcher Ausdruck aus?
replace( /<div\s+align="([^>"]+)">([^<]*)</div>/, "[$1]$2[/$1]" )
(ungetestet!) Allerdings fehlt hier noch das "uppercasing". Das müßtest Du in einem weiteren Schritt erledigen.
Gibt es eine Bessere möglichkeit?
Ja! Wenn Du auf der DOM Struktur arbeiten würdest.
-- Skeeve
Hi, danke für die Antwort
Aber ich will ja nicht alle <...>'s ausschließen sondern nur die <div..>'s meinetwegen geht das auch so..
Ja? Was ist denn die DOM-Struktur?
Moin!
Ja? Was ist denn die DOM-Struktur?
Ist zwar nur für Mozilla/Gecko die Dokumentation, aber vielleicht hilft's: http://developer.mozilla.org/en/docs/Gecko_DOM_Reference
Prinzip wäre, einem hidden div den HTML source als innnerHTML zuzuweisen und dann auf der Baumstruktur zu arbeiten. Dadurch hättest Du dann automatisch die richtige Verschachtelung. Im Prinzip mußt Du nur rekursiv alle Kinder des div abarbeiten und passend ausgeben. Allerdings würde das mir im Moment etwas zu weit führen, das hier komplett auszuarbeiten. Sorry ;-)
-- Skeeve
danke aber wie soll ich damit denn arbeiten? klar will ich jedes einzelne child einzeln abarbeiten aber ich verstehe nicht was ich da mit nem blind-div und innerhtml und blabla machen soll.
naja, wie negiert man denn eine ganze zeichenkette? also "alles ausser xyz"... mit [^abc] kann man ja nur bestimmte zeichen negieren..
Moin!
Hier mal ein Beispiel damit Du loslegen kannst.
Das Blinddiv ist aber noch nicht blind, damit Du siehst, was passiert.
<html>
<head>
<script language="JavaScript" type="text/JavaScript" >
function bbcode() {
html= document.mainform.eingabe.value;
blinddiv= document.getElementById('blinddiv');
blinddiv.innerHTML= html;
document.mainform.ausgabe.value= convert_to_bbcode( blinddiv );
}
function convert_to_bbcode( p ) {
var preresult= '';
var postresult= '';
var result= '';
switch( p.nodeName ) {
case 'DIV':
var align= p.getAttribute( 'align' );
if ( align ) {
preresult= '[' + align.toUpperCase() + ']';
postresult= '[/' + align.toUpperCase() + ']';
}
break;
case 'B':
preresult= '[B]';
postresult='[/B]';
break;
case '#text':
return p.textContent;
break;
default:
preresult= ' ?? ' + p.nodeName + ' ?? ';
break;
}
var child= p.firstChild;
while (child) {
result+= convert_to_bbcode( child );
child= child.nextSibling;
}
return preresult + result + postresult;
}
</script>
</head>
<body>
<form method="post" name="mainform" action="http://www.google.de/" onsubmit="return false;">
<textarea id="eingabe" cols="75" rows="10">
<b>
bold
<div align="left">
left
<div align="right">
right
<div align="center">
center
</div>
</div>
</div>
</b>
</textarea>
<button onclick="bbcode()">mach</button>
<textarea id="ausgabe" readonly cols="75" rows="10"></textarea>
</form>
<div id="blinddiv"></div>
</body>
</html>
Das ' ?? ' + p.nodeName + ' ?? ' dient dazu, Dir zu helfen, noch nicht implementierte Elemente zu identifizieren. Ich habe ja bisher nur <b> und <div> implementiert. Wieso eigentlich div und nicht span?
-- Skeeve
super, vielen dank für deine mühe! Werde mir das mal anschauen :-)
Div und nicht Span.. Der HTMLcode wird vom Browser generiert ich hab auf dessen eigenarten leider keinen einfluss. und der nimmt da halt div.
mfg PoWl