validate test regular online one golang html regex parsing html-parsing

test - ¿Cómo funcionan los análisis HTML si no están usando regexp?



regex perl online (5)

Entonces, ¿cómo funciona un analizador de HTML? ¿No usa expresiones regulares para analizar?

Bueno no.

Si recurre a su cerebro a una teoría del curso de computación, si tomó uno, o un curso de compiladores, o algo similar, puede recordar que hay diferentes tipos de idiomas y modelos computacionales. No estoy calificado para entrar en detalles, pero puedo revisar algunos de los puntos principales con usted.

El tipo más simple de lenguaje y computación (para estos propósitos) es un lenguaje regular. Estos pueden generarse con expresiones regulares y reconocerse con autómatas finitos. Básicamente, eso significa que las cadenas de "análisis" en estos lenguajes usan estado, pero no memoria auxiliar. HTML ciertamente no es un lenguaje regular. Si lo piensas bien, la lista de etiquetas puede anidarse arbitrariamente. Por ejemplo, las tablas pueden contener tablas, y cada tabla puede contener muchas etiquetas anidadas. Con expresiones regulares, es posible que pueda elegir un par de etiquetas, pero ciertamente no anidadas de forma arbitraria.

Un lenguaje clásico simple que no es regular es paréntesis correctamente emparejados. Por más que lo intentes, nunca podrás construir una expresión regular (o un autómata finito) que siempre funcione. Necesita memoria para realizar un seguimiento de la profundidad de anidamiento.

Una máquina de estado con una pila para memoria es la siguiente fortaleza del modelo computacional. Esto se llama autómata push-down y reconoce los lenguajes generados por gramáticas libres de contexto. Aquí, podemos reconocer paréntesis correctamente emparejados, de hecho, una pila es el modelo de memoria perfecto para ello.

Bueno, ¿es esto lo suficientemente bueno para HTML? Tristemente no. Tal vez para super-duper XML cuidadosamente validado, en realidad, en el que todas las etiquetas siempre se alinean perfectamente. En HTML del mundo real, puede encontrar fácilmente fragmentos como <b><i>wow!</b></i> . Obviamente, esto no anida, por lo que para analizarlo correctamente, una pila simplemente no es lo suficientemente potente.

El siguiente nivel de computación son los lenguajes generados por gramáticas generales y reconocidos por las máquinas de Turing. En general, se acepta que es efectivamente el modelo computacional más sólido que existe: una máquina de estado, con memoria auxiliar, cuya memoria puede modificarse en cualquier lugar. Esto es lo que pueden hacer los lenguajes de programación. Este es el nivel de complejidad donde vive HTML.

Para resumir todo aquí en una oración: para analizar HTML general, necesita un lenguaje de programación real, no una expresión regular.

HTML se analiza de la misma manera en que se analizan otros lenguajes: lexing y parsing. El paso lexing divide la secuencia de caracteres individuales en tokens significativos. El paso de análisis ensambla los tokens, usando estados y memoria, en un documento lógicamente coherente en el que se puede actuar.

Veo preguntas todos los días preguntando cómo analizar o extraer algo de una cadena HTML y la primera respuesta / comentario es siempre "¡No use RegEx para analizar HTML, no sea que sienta la ira!" (esa última parte a veces se omite).

Esto es bastante confuso para mí, siempre pensé que, en general, la mejor manera de analizar cualquier cadena complicada es usar una expresión regular. Entonces, ¿cómo funciona un analizador de HTML? ¿No usa expresiones regulares para analizar?

Un argumento particular para usar una expresión regular es que no siempre hay una alternativa de análisis (como JavaScript, donde DOMDocument no es una opción disponible universalmente). jQuery, por ejemplo, parece funcionar bien usando una expresión regular para convertir una cadena HTML a nodos DOM.

No estoy seguro de si CW esto o no, es una pregunta genuina que quiero que me respondan y no pretende ser un hilo de discusión.


El análisis de HTML es la transformación de un texto lineal en una estructura de árbol. Las expresiones regulares generalmente no pueden manejar estructuras de árbol. La expresión regular que necesita en cada punto para obtener el próximo token cambia todo el tiempo. Puede usar expresiones regulares en un analizador, pero necesitará una matriz completa de expresiones regulares para cada posible estado de análisis sintáctico.


Las expresiones regulares son solo una forma de analizador. Un analizador de HTML honesto será significativamente más complicado de lo que se puede expresar en expresiones regulares, utilizando el descenso recursivo , la predicción y varias otras técnicas para interpretar correctamente el texto. Si realmente quieres adentrarte en él, puedes consultar lex y yacc y herramientas similares.

La prohibición de usar expresiones regulares para el análisis de HTML probablemente debería escribirse más correctamente como: "No use expresiones regulares ingenuas para analizar HTML ..." (para que no sienta la ira) "... y trate los resultados con precaución". Para ciertos objetivos específicos, una expresión regular puede ser perfectamente adecuada, pero debe ser muy cuidadoso al estar consciente de las limitaciones de su expresión regular y tan cuidadoso como sea apropiado para la fuente del texto que está analizando (por ejemplo, si es la entrada del usuario, tenga mucho cuidado).


Si desea tener una solución al 100%: debe escribir su propio código personalizado que recorre el carácter carácter por carácter HTML y debe tener una gran cantidad de lógica para determinar si debe detener el nodo actual y comenzar el siguiente.

La razón es que este es un HTML válido:

<ul> <li>One <li>Two <li>Three </ul>

Pero también lo es esto:

<ul> <li>One</li> <li>Two</li> <li>Three</li> </ul>

Si está de acuerdo con la "solución del 90%": entonces, usar un analizador XML para cargar un documento está bien. O usando Regex (aunque el xml es más fácil si eres dueño del contenido).