2009-05-04 9 views
5

He estado investigando este problema que solo parece empeorar cuanto más profundizo.expresión regular en javascript cadena dividida, compatibilidad con el navegador problema

empecé inocentemente tratando de utilizar esta expresión para dividir una cadena de etiquetas HTML 'br':

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

Esto funciona en todos los navegadores (FF, Safari, Chrome), excepto IE7 e IE8 con el ejemplo texto de entrada como esta:

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

Tenga en cuenta que el texto de ejemplo contiene un espacio antes del '/', y precede a una nueva línea.

ambos de los siguientes coincidirá con todas las etiquetas HTML en todos los navegadores:

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

Sin embargo, es sorprendente (al menos para mí), este no trabajo en FF y Chrome:

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

Editar:

Esto (sugerido varias veces en las respuestas a continuación,) no funciona en IE 7 u 8:

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

(Se hizo el trabajo en Chrome y FF.)

Mi pregunta es: ¿alguien sabe una expresión que funciona en todos los navegadores actuales para que coincida con las etiquetas 'br' anteriores (pero no otras etiquetas HTML) . Y ¿alguien puede confirmar que el último ejemplo anterior debe ser una coincidencia válida ya que dos caracteres están presentes en el texto de ejemplo antes del '>'.

PD: mi doctype es HTML de transición.

Editar:

creo que tengo pruebas este es específico para el string.split() Comportamiento en IE y no regex en general. Debes usar split() para ver este problema. También encontré una matriz de prueba que muestra una tasa de fallas de aproximadamente 30% para los casos de prueba de split() cuando lo ejecuté en IE. Las mismas pruebas pasaron 100% en Chrome FF y:

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

Hasta el momento, todavía no he encontrado una solución para IE, y la biblioteca proporcionada por el autor de esa matriz de prueba no fijó este caso.

+0

PPS - Actualmente no estoy probando IE6 u Opera, pero no dude en analizar estos si es relevante. –

Respuesta

15

La razón por la que su código no funciona es porque el IE analiza el HTML y hace que las etiquetas en mayúscula cuando lo lees a través de innerHTML. Por ejemplo, si usted tiene HTML así:

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

Y entonces utilizar este Javascript (en IE):

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

Usted obtendrá un cuadro de alerta con esto:

Hello<BR>World 

Observe que el <BR> ahora está en mayúscula. Para solucionar esto, simplemente agregue la bandera i además del indicador g para hacer que la expresión regular no distinga entre mayúsculas y minúsculas y funcionará como esperaba.

+0

Sí, tienes razón. Un millón de gracias, y ahora sé algo nuevo sobre innerHTML en IE. –

6

Prueba con esto:

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

Aconsejaría/gi, ya que nunca se sabe cómo alguien va a encapsular sus etiquetas –

+0

Esto funciona en Chrome y FF, y falla en IE. Le doy +1 porque * debería * funcionar. –

+0

Por cierto, como ahora me doy cuenta, NO falla cuando se usa exactamente como lo proporcionó aquí. Omití la bandera 'i' porque estaba trabajando con una fuente minúscula conocida. Lección aprendida: IE etiquetas up-cases en innerHTML. –

0

expresiones regulares son fundamentalmente malo en análisis de HTML (ver Can you provide some examples of why it is hard to parse XML and HTML with a regex? por qué). Lo que necesitas es un analizador HTML. Ver Can you provide an example of parsing HTML with your favorite parser? para ejemplos usando una variedad de analizadores.

En particular, le puede interesar el JavaScript+DOM answer.

+2

Sí, no pretendo hacer un analizador HTML completo, y este no es un entorno jQuery. Tenga en cuenta que no hay ningún problema con la gestión de expresiones regulares esto, pero un problema de compatibilidad con el navegador en IE 7 y 8. (Aunque el ejemplo que falló en FF también me desconcierta.) –

+1

"Regexes son fundamentalmente malos en el análisis de HTML" - no si sabes cómo será la entrada. – nickf

+0

@Walt Gordon Jones No es una cuestión de lo que intentas hacer o no, las expresiones regulares no pueden manejar HTML, no es lo que hacen bien, al menos echa un vistazo a hacerlo con un analizador sintáctico, siempre puede usar el DOM. –

1

En lugar de

/<br.*?>/ 

podría intentar

/<br[^>]*>/ 

es decir, a juego "<br", seguido de caracteres que no sean '>', seguido de '>'.

+0

Gracias, todavía falla en IE solamente. –

0

Bueno, por desgracia no tengo una amplia variedad de navegadores en el trabajo (solo IE - suspiro) pero de buenas a primeras puedo ver una manera de optimizar su expresión regular:

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

El personaje en línea la definición de clase [^>] indica a la expresión que coincida con cualquier carácter EXCEPTO el signo de mayor que. También es posible que desee hacer que sea insensible a mayúsculas y minúsculas (pase gi al final no solo g).

+0

En algunos motores de expresiones regulares, el *? El operador indica coincidencia no codiciosa, donde /.*?>/ coincidirá con cualquier carácter hasta el * primer * punto donde coincida el siguiente texto. Sin?, /.*>/ coincide hasta el * último * punto donde coincide el siguiente texto. –

+0

Sí, quiero la primera coincidencia (obviamente), pero la [^>] parece una forma inteligente de forzar la primera coincidencia, ya que esa es la única forma de satisfacer la condición. De todos modos, incluso las variaciones que deberían ser codiciosas no coinciden en absoluto en IE. –

0

Probado en Firefox 3 & IE7:

/<br.*?>/gi 

Inténtelo usted mismo aquí: http://jsbin.com/ofoke

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

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

Creo que he determinado que el problema es específicamente con String.split en IE. (Su ejemplo usa String replace.) Mire esta matriz de caso de prueba para split(): http://stevenlevithan.com/demo/split.cfm IE falla alrededor del 30% de los casos. FF y Chrome pasan esta matriz al 100%. –

+0

¿Podría intentar hacer algo así como reemplazar utilizando una expresión regular, para reemplazar las etiquetas
con "|| BR ||" y luego usa un no-regex normal para dividirlo? input.replace (/ /gi, '|| BR ||') split ("|| BR ||"); ¿Eso funciona? – nickf

0

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

partidos

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

he probado en here IE.6. Si March está bien, el js ciertamente podría dividirlo de acuerdo con la expresión regular.

Cuestiones relacionadas