2009-05-04 11 views
5

Ich habe dieses Problem untersucht, das nur schlimmer zu werden scheint, je mehr ich tiefer graben.Regulärer Ausdruck in JavaScript String Split, Browserkompatibilitätsproblem

begann ich unschuldig genug versucht, diesen Ausdruck zu verwenden, um eine Zeichenfolge auf HTML 'br' Tags zu spalten:

T = captions.innerHTML.split(/<br.*?>/g); 

Diese in jedem Browser funktionieren (FF, Safari, Chrome), außer IE7 und IE8 mit Beispiel Eingabetext wie folgt aus:

is invariably subjective. <br /> 
The less frequently used warnings (Probably/Possibly) <br /> 

Bitte beachten Sie, dass das Beispiel Text ein Leerzeichen vor dem ‚/‘ enthält, und geht eine neue Zeile.

die beiden folgenden werden alle HTML-Tags in jedem Browser entsprechen:

T = captions.innerHTML.split(/<.*?>/g); 
T = captions.innerHTML.split(/<.+?>/g); 

jedoch überraschenderweise (zumindest für mich), das nicht Arbeit in FF und Chrome:

T = captions.innerHTML.split(/<br.+?>/g); 

Edit:

Diese (vorgeschlagen mehrmals in den Antworten unten) auf IE nicht 7 oder 8 funktioniert:

T = captions.innerHTML.split(/<br[^>]*>/g); 

(Es hat die Arbeit an Chrome und FF.)

Meine Frage ist: weiß jemand einen Ausdruck, der die ‚br‘ Tags übereinstimmen oben (aber nicht andere HTML-Tags) in allen gängigen Browsern . Und kann jemand bestätigen, dass das letzte Beispiel oben eine gültige Übereinstimmung sein sollte, da zwei Zeichen im Beispieltext vor dem '>' vorhanden sind.

PS - mein Doctype ist HTML-Übergang.

Edit:

Ich glaube, ich habe Beweise, die dies ist spezifisch für die string.split() Verhalten auf IE, und in der Regel nicht regex. Sie müssen split() verwenden, um dieses Problem zu sehen. Ich habe auch eine Testmatrix gefunden, die eine Fehlerrate von ungefähr 30% für split() Testfälle zeigt, wenn ich es auf IE lief. Die gleichen Tests bestanden zu 100% auf FF und Chrome:

http://stevenlevithan.com/demo/split.cfm

Bisher habe ich noch keine Lösung für IE gefunden, und die Bibliothek vom Autor dieser Testmatrix zur Verfügung gestellt hat diesen Fall nicht beheben.

+0

PPS - Ich teste nicht IE6 oder Opera, aber ich spreche gerne, wenn es relevant ist. –

Antwort

15

Der Grund Code funktioniert nicht, weil IE das HTML analysiert und macht die Großbuchstaben-Tags, wenn Sie lesen es durch innerHTML. Zum Beispiel, wenn Sie HTML wie dieses:

<div id='box'> 
Hello<br> 
World 
</div> 

Und dann verwenden Sie diese Javascript (in IE):

alert(document.getElementById('box').innerHTML); 

Sie eine Warnung mit diesem erhalten:

Hello<BR>World 

Beachten Sie, dass die <BR> jetzt in Großbuchstaben ist. Um dies zu beheben, fügen Sie einfach das i-Flag zusätzlich zum g-Flag hinzu, damit die Regex nicht von der Groß- und Kleinschreibung betroffen ist, und es funktioniert wie erwartet.

+0

Ja, Sie sind genau richtig. Eine Million Dank, und jetzt weiß ich etwas Neues über innerHTML auf IE. –

6

Versuchen Sie dieses:

/<br[^>]*>/gi 
+1

Ich würde raten/gi, da Sie nie wissen, wie jemand ihre Tags behandelt –

+0

Das funktioniert in Chrome und FF, und schlägt in IE fehl. Ich gebe +1 weil es * funktionieren * sollte. –

+0

BTW, wie ich jetzt realisiere, scheitert es NICHT, wenn es genau so benutzt wird, wie du es hier angegeben hast. Ich habe die "i" -Flagge weggelassen, weil ich mit einer bekannten Kleinbuchstabenquelle gearbeitet habe. Lektion gelernt: IE Up-Cases-Tags in InnerHTML. –

0

Regexes grundsätzlich schlecht sind bei der HTML-Analyse (siehe Can you provide some examples of why it is hard to parse XML and HTML with a regex? warum). Was Sie brauchen, ist ein HTML-Parser. Beispiele finden Sie unter Can you provide an example of parsing HTML with your favorite parser? mit einer Vielzahl von Parsern.

Insbesondere könnten Sie in der JavaScript+DOM answer interessiert sein.

+2

Ja, ich beabsichtige nicht, einen vollständigen HTML-Parser zu erstellen, und dies ist keine jQuery-Umgebung. Bitte beachten Sie, es gibt kein Problem mit der Regex-Behandlung, sondern ein Browser-Kompatibilitäts-Problem in IE 7 und 8. (Obwohl das Beispiel, das in FF gescheitert ist, verwirrt mich auch.) –

+1

"Regexes sind grundsätzlich schlecht im HTML-Parsing" - nicht wenn Sie wissen, wie die Eingabe aussehen wird. – nickf

+0

@Walt Gordon Jones Es ist nicht eine Frage dessen, was Sie beabsichtigen zu tun oder nicht, Regexes können nicht mit HTML umgehen, es ist nicht das, was sie gut sind, zumindest einen Blick darauf werfen, es mit einem Parser zu tun kann immer das DOM verwenden. –

1

Statt

/<br.*?>/ 

könnten Sie versuchen,

/<br[^>]*>/ 

heißt "<br" passend, gefolgt von beliebigen Zeichen außer '>', gefolgt von '>'.

+0

Danke, schlägt immer noch nur in IE. –

0

Nun, leider habe ich nicht eine Vielzahl von Browsern bei der Arbeit haben (nur IE - seufz), aber auf Anhieb kann ich sehen, wie man Ihre regex zu optimieren:

T = captions.innerHTML.split(/<br[^>]*?>/g); 

Der Inline-Charakter Klassendefinition [^>] weist den Ausdruck an, ein beliebiges Zeichen außer dem Größer-als-Zeichen zu finden. Sie können auch die Groß-/Kleinschreibung ignorieren (übergeben Sie gi am Ende nicht nur g).

+0

In einigen regulären Ausdrücken ist der *? Der Operator gibt eine nicht gierige Übereinstimmung an, wobei /.*?>/ mit jedem Zeichen bis zum * ersten * Punkt übereinstimmt, an dem der folgende Text übereinstimmt. Ohne das?, /.*>/ entspricht es dem * letzten * Punkt, an dem der folgende Text übereinstimmt. –

+0

Ja, will das erste Match (offensichtlich), aber die [^>] sieht wie eine clevere Möglichkeit aus, das erste Match zu erzwingen, da dies die einzige Möglichkeit ist, die Bedingung zu erfüllen. Unabhängig davon, sogar die Variationen, die gierig sein sollten, stimmen überhaupt nicht unter IE überein. –

0

in Firefox 3 & IE7 getestet:

/<br.*?>/gi 

es selbst versuchen hier: http://jsbin.com/ofoke

var input = "one <br/>\n" 
      + "two <br />\n" 
      + "three <br>\n" 
; 

alert(input.replace(/<br.*?>/gi, '')); 
+0

Ich glaube, ich habe festgestellt, das Problem ist speziell mit String.split auf IE. (In Ihrem Beispiel wird String replace verwendet.) Sehen Sie sich diese Testfallmatrix für split() an: http://stevenlevithan.com/demo/split.cfm IE schlägt in etwa 30% der Fälle fehl. FF und Chrome bestehen diese Matrix zu 100%. –

+0

könnten Sie dann versuchen, etwas wie eine Ersetzung mit einem Regex zu tun, um
Tags durch "|| BR ||" zu ersetzen und dann einen normalen Nicht-Regex verwenden, um es zu teilen? input.replace (/ /gi, '|| BR ||') .split ("|| BR ||"); Funktioniert das? – nickf

0

< \ s br \ s /? \ S *>

Streichhölzer

<br>, <br />, <br>,<br/> 

I getestet here in IE.6. Wenn marsch OK ist, könnte die js es entsprechend der regexp teilen.