Pregunta RegEx match las etiquetas abiertas, excepto las etiquetas autocontenidas XHTML


Necesito hacer coincidir todas estas etiquetas de apertura:

<p>
<a href="foo">

Pero no estos:

<br />
<hr class="foo" />

Se me ocurrió esto y quería asegurarme de que lo hice bien. Solo estoy capturando el a-z.

<([a-z]+) *[^/]*?>

Yo creo que dice:

  • Encuentra un menos que, entonces
  • Encuentre (y capture) a-z una o más veces, luego
  • Encuentra cero o más espacios, luego
  • Encuentra cualquier personaje cero o más veces, codicioso, excepto /, entonces
  • Encuentra un mayor que

¿Tengo eso correcto? Y más importante, ¿qué piensas?


1324
2017-09-27 04:01


origen


Respuestas:


No puede analizar [X] HTML con expresiones regulares. Porque HTML no puede ser analizado por regex. Regex no es una herramienta que se puede usar para analizar correctamente HTML. Como ya he respondido muchas veces en las preguntas sobre HTML y expresiones regulares, el uso de expresiones regulares no le permitirá consumir HTML. Las expresiones regulares son una herramienta que no es lo suficientemente sofisticada como para entender los constructos empleados por HTML. HTML no es un lenguaje normal y, por lo tanto, no puede ser analizado por expresiones regulares. Las consultas Regex no están equipadas para descomponer HTML en sus partes significativas. tantas veces pero no me está llegando Incluso las expresiones regulares irregulares mejoradas utilizadas por Perl no están a la altura de analizar HTML. Nunca me harás crackear. HTML es un lenguaje de suficiente complejidad que no puede ser analizado por expresiones regulares. Incluso Jon Skeet no puede analizar HTML utilizando expresiones regulares. Cada vez que intenta analizar HTML con expresiones regulares, el hijo impío llora la sangre de las vírgenes, y los piratas informáticos rusos pwn su webapp. Analizar HTML con expresiones regulares llama a las almas contaminadas al reino de los vivos. HTML y expresiones regulares van juntas como el amor, el matrimonio y el infanticidio ritual. El <center> no puede contenerlo, es demasiado tarde. La fuerza de expresiones regulares y HTML juntas en el mismo espacio conceptual destruirá tu mente como una masilla acuosa. Si analizas HTML con expresiones regulares las estas cediendo a Ellos y sus formas blasfemas que nos condenan a todos a un trabajo inhumano para el Uno cuyo Nombre no puede expresarse en el Plano Multilingüe Básico, él viene. HTML-plus-regexp licuará las necesidades del ser consciente mientras observas, tu psique marchitándose en la embestida del horror. Los analizadores de HTML basados ​​en Rege̿̔̉x son el cáncer que está matando a StackOverflow es demasiado tarde, es demasiado tarde, no podemos ser salvados la transgesión de un virus garantiza que la expresión regular consumirá todo el tejido vivo (excepto el HTML que no puede, como se profetizó anteriormente) querido señor, ayúdanos cómo puede alguien sobrevivir a este flagelo El uso de expresiones regulares para analizar HTML ha condenado a la humanidad a una eternidad de terror y agujeros de seguridad usando regex como una herramienta para procesar HTML establece un breach entre este mundo y el temible reino de las entidades corruptas (como las entidades SGML, pero más corrupto) un simple destellose del mundo de regex analizadores para HTML ins insTantly transporte una pconciencia del rogrammer into a world de gritos incesantes, viene, el pestilente slcon la infección regex wilYo devoro tu HTAnalizador ML, aplicación y existencia para todos los tiempos como Visual Basic solo peor él viene él comes no fiGht he com̡e̶s, ̕h̵iS un̨ho͞ly radiańcé demarcando todo enlightenment, etiquetas HTML lea͠ki̧n͘g fr̶ǫm ̡yo ͟ur eye͢s̸ ͏l̕ik͏e liqUid pain, la canción de re̸gular exp reanálisis de ssion ExtiNigish las voces de mortal hombre de la spAquí puedo ver que se puede ver ͚̖͔̙î̩t͎̩͔̋ es hermoso tél final snuffing of la mentiras del Hombre TODO ES LOŚ͖̩͇̗̪̏̈T ALL I S LOST the pon̷y él vienes él c̶̮omes él coyoS tél hechizoo permeates all MI FACE MI CARA ᵒh Dios no NO NOO̼O O NΘ detener tél an * ̶͑̾̾ ͇̫͛͆̾ͫ̑͆g͇̫͛͆̾ͫ̑͆l͖͉̗̩̳̟̍ͫͥͨe̠̅s ͎a̧͈͖r̽̾̈́͒͑e norteOt rè̑ͧ̌aͨl̘̝̙ͤ̾̆ ZA̡͊͠͝LGΌ ISͮ҉̯͈͕̹̘ TO͇̹̺Ɲ̴ȳ̳ TH̘Ë͖̉ ̯͍̭P̯͍̭O̚ N̐Y̡ H̸̡̪̯ͨ͊̽̅̾Ȩ̬̩̾͛ͪ̈͘ ͮ͏̮̪̝͍C̷̙̝͖ͭ̏ͥͮ͟Oͮ͏̮̪̝͍M̖͊̒ͪͩͬ̚̚͜Ȇ̴̟̟͙̞ͩ͌͝S̨̥̫͎̭ͯ̿̔


¿Has intentado utilizar un analizador XML en su lugar?


Nota del moderador

Esta publicación está bloqueada para evitar ediciones inadecuadas de su contenido. La publicación se ve exactamente como se supone que debe verse, no hay problemas con su contenido. Por favor, no lo marques para nuestra atención.


4422



Si bien es cierto que pedir expresiones regulares para analizar arbitrario HTML es como pedirle a un principiante que escriba un sistema operativo, a veces es apropiado analizar un limitado, conocido conjunto de HTML.

Si tiene un pequeño conjunto de páginas HTML de las que desea raspar datos y luego cosas en una base de datos, las expresiones regulares podrían funcionar bien. Por ejemplo, hace poco quise obtener los nombres, las fiestas y los distritos de los representantes federales australianos, que obtuve del sitio web del Parlamento. Este fue un trabajo limitado, de una sola vez.

Regexes funcionó muy bien para mí, y fueron muy rápidos de configurar.


2915



Creo que el error aquí es que HTML es una Gramática tipo 2 de Chomsky (gramática libre de contexto) y RegEx es un Gramática Chomsky Tipo 3 (gramática regular). Dado que una gramática tipo 2 es fundamentalmente más compleja que una gramática tipo 3 (ver el Jerarquía de Chomsky), no puedes hacer que esto funcione. Pero muchos intentarán, algunos reclamarán el éxito y otros encontrarán la culpa y los desordenarán por completo.


1799



No escuches a estos tipos. Usted en realidad poder Analice las gramáticas libres de contexto con expresiones regulares si divide la tarea en partes más pequeñas. Puede generar el patrón correcto con un script que haga cada uno de estos en orden:

  1. Resuelve el problema de detención.
  2. Cuadre un círculo (simule el método de "regla y compás" para esto).
  3. Resuelva el problema del vendedor ambulante en O (log n). Necesita ser rápido o el generador se colgará.
  4. El patrón será bastante grande, así que asegúrese de tener un algoritmo que comprima datos aleatoriamente.
  5. Casi allí, solo divide todo en cero. Pan comido.

Todavía no he resuelto la última parte, pero sé que me estoy acercando. Mi código sigue tirando CthulhuRlyehWgahnaglFhtagnExceptions últimamente, así que voy a portarlo a VB 6 y usar On Error Resume Next. Actualizaré el código una vez que investigue esta extraña puerta que acaba de abrirse en la pared. Hmm.

PD Pierre de Fermat también descubrió cómo hacerlo, pero el margen en el que estaba escribiendo no era lo suficientemente grande para el código.


1167



Renuncia: use un analizador si tiene la opción. Eso dijo ...

Esta es la expresión regular que uso (!) Para que coincida con las etiquetas HTML:

<(?:"[^"]*"['"]*|'[^']*'['"]*|[^'">])+>

Puede que no sea perfecto, pero ejecuté este código a través de un mucho de HTML. Tenga en cuenta que incluso atrapa cosas extrañas como <a name="badgenerator"">, que aparecen en la web.

Supongo que para que no coincida con las etiquetas autocontenidas, o bien querrías usar KobiMirada atrás negativa:

<(?:"[^"]*"['"]*|'[^']*'['"]*|[^'">])+(?<!/\s*)>

o simplemente combine si y si no.

Para los detractores: Este es código de trabajo de un producto real. Dudo que nadie que lea esta página tenga la impresión de que es socialmente aceptable usar expresiones regulares en HTML.

Advertencia: Debería tener en cuenta que esta expresión regular aún se rompe en presencia de bloques CDATA, comentarios y guiones y elementos de estilo. La buena noticia es que puedes deshacerte de aquellos que usan una expresión regular ...


1016



Hay personas que te dirán que la Tierra es redonda (o que la Tierra es un esferoide achatado si quieren usar palabras extrañas). Están mintiendo.

Hay personas que le dirán que las expresiones regulares no deberían ser recursivas. Ellos te están limitando. Necesitan subyugarte, y lo hacen manteniéndote en la ignorancia.

Puedes vivir en su realidad o tomar la pastilla roja.

Como Lord Marshal (¿es pariente de la clase .NET de Marshal?), He visto el Inferior Stack Based Regex-Verse y devuelto con potestades conocimiento que no puedes imaginar Sí, creo que había uno o dos ancianos que los protegían, pero estaban viendo fútbol en la televisión, así que no fue difícil.

Creo que el caso de XML es bastante simple. El RegEx (en la sintaxis .NET), desinflado y codificado en base64 para que sea más fácil de comprender por su mente débil, debería ser algo como esto:

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
+r/vD34mUADO1P4/AQAA//8=

Las opciones para establecer es RegexOptions.ExplicitCapture. El grupo de captura que estás buscando es ELEMENTNAME. Si el grupo de captura ERROR no está vacío, entonces hubo un error de análisis y la Regex se detuvo.

Si tiene problemas para reconvertirlo a una expresión regular legible por humanos, esto debería ayudar:

static string FromBase64(string str)
{
    byte[] byteArray = Convert.FromBase64String(str);

    using (var msIn = new MemoryStream(byteArray))
    using (var msOut = new MemoryStream()) {
        using (var ds = new DeflateStream(msIn, CompressionMode.Decompress)) {
            ds.CopyTo(msOut);
        }

        return Encoding.UTF8.GetString(msOut.ToArray());
    }
}

Si no está seguro, no, no estoy bromeando (pero tal vez estoy mintiendo). Funcionará. He creado toneladas de pruebas unitarias para probarlo, e incluso he usado (parte de) pruebas de conformidad. Es un tokenizador, no un analizador completo, por lo que solo dividirá el XML en sus tokens de componentes. No analizará ni integrará las DTD.

Oh ... si quieres el código fuente de la expresión regular, con algunos métodos auxiliares:

regex para tokenizar un xml o la expresión regular completa 


452



En shell, puedes analizar HTML utilizando:

  • sed aunque:

    1. Turing.sed
    2. Escribir analizador HTML (tarea)
    3. ???
    4. ¡Lucro!
  • hxselect de html-xml-utils paquete

  • vim/ex (que puede fácilmente saltar entre las etiquetas html), por ejemplo:

    • eliminar etiqueta de estilo con código interno:

      $ curl -s http://example.com/ | ex -s +'/<style.*/norm nvatd' +%p -cq! /dev/stdin
      
  • grep, por ejemplo:

    • extraer html externo de H1:

      $ curl -s http://example.com/ | grep -o '<h1>.*</h1>'
      <h1>Example Domain</h1>
      
    • extrayendo el cuerpo:

      $ curl -s http://example.com/ | tr '\n' ' ' | grep -o '<body>.*</body>'
      <body> <div> <h1>Example Domain</h1> ...
      
  • html2text al análisis de texto sin formato:

  • utilizando xpath (XML::XPath módulo perl), ver ejemplo aquí

  • Perl o Python (ver Ejemplo de @Gilles)

  • para analizar múltiples archivos a la vez, ver: ¿Cómo analizar cientos de archivos de código fuente html en shell?


Relacionado (por qué no deberías usar la coincidencia de expresiones regulares):


285



Estoy de acuerdo en que la herramienta adecuada para analizar XML y especialmente HTML es un analizador y no un motor de expresiones regulares. Sin embargo, como otros han señalado, a veces el uso de una expresión regular es más rápido, más fácil y hace el trabajo si conoce el formato de datos.

Microsoft en realidad tiene una sección de Mejores prácticas para expresiones regulares en .NET Framework y específicamente habla sobre Considere [ing] la fuente de entrada.

Las expresiones regulares tienen limitaciones, pero ¿ha considerado lo siguiente?

.NET Framework es único cuando se trata de expresiones regulares, ya que admite Definiciones del grupo de equilibrio.

Por esta razón, creo que puedes analizar XML utilizando expresiones regulares. Sin embargo, tenga en cuenta que debe ser XML válido (los navegadores son muy indulgentes con HTML y permiten una mala sintaxis XML dentro de HTML) Esto es posible ya que la "Definición del Grupo de Equilibrio" permitirá que el motor de expresiones regulares actúe como un PDA.

Cita del artículo 1 citado anteriormente:

Motor de expresión regular .NET

Como se describió anteriormente, las construcciones adecuadamente equilibradas no pueden describirse por   una expresión regular. Sin embargo, el motor de expresión regular .NET   proporciona algunas construcciones que permiten construcciones equilibradas para ser   Reconocido.

  • (?<group>) - empuja el resultado capturado en la pila de captura con   el nombre del grupo
  • (?<-group>) - aparece la captura más alta con el grupo de nombre de la   pila de captura.
  • (?(group)yes|no) - coincide con la parte sí si existe un grupo   con el grupo de nombre de lo contrario no coincide con ninguna parte.

Estas construcciones permiten una expresión regular .NET para emular una   PDA restringido al permitir esencialmente versiones simples de la pila   operaciones: push, pop y empty. Las operaciones simples son más o menos   equivalente a incrementar, decrementar y comparar a cero respectivamente.   Esto permite que el motor de expresiones regulares .NET reconozca un   subconjunto de lenguajes sin contexto, en particular los que solo   requiere un contador simple. Esto a su vez permite el uso no tradicional   Expresiones regulares de .NET para reconocer el equilibrio individual correctamente   construcciones

Considera la siguiente expresión regular:

(?=<ul\s+id="matchMe"\s+type="square"\s*>)
(?>
   <!-- .*? -->                  |
   <[^>]*/>                      |
   (?<opentag><(?!/)[^>]*[^/]>)  |
   (?<-opentag></[^>]*[^/]>)     |
   [^<>]*
)*
(?(opentag)(?!))

Usa las banderas:

  • Linea sola
  • IgnorePatternWhitespace (no es necesario si contrae expresiones regex y elimina todos los espacios en blanco)
  • IgnoreCase (no es necesario)

Expresión regular explicada (en línea)

(?=<ul\s+id="matchMe"\s+type="square"\s*>) # match start with <ul id="matchMe"...
(?>                                        # atomic group / don't backtrack (faster)
   <!-- .*? -->                 |          # match xml / html comment
   <[^>]*/>                     |          # self closing tag
   (?<opentag><(?!/)[^>]*[^/]>) |          # push opening xml tag
   (?<-opentag></[^>]*[^/]>)    |          # pop closing xml tag
   [^<>]*                                  # something between tags
)*                                         # match as many xml tags as possible
(?(opentag)(?!))                           # ensure no 'opentag' groups are on stack

Puedes probar esto en Un mejor probador de expresiones regulares de .NET.

Usé la fuente de muestra de:

<html>
<body>
<div>
   <br />
   <ul id="matchMe" type="square">
      <li>stuff...</li>
      <li>more stuff</li>
      <li>
          <div>
               <span>still more</span>
               <ul>
                    <li>Another &gt;ul&lt;, oh my!</li>
                    <li>...</li>
               </ul>
          </div>
      </li>
   </ul>
</div>
</body>
</html>

Esto encontró el partido:

   <ul id="matchMe" type="square">
      <li>stuff...</li>
      <li>more stuff</li>
      <li>
          <div>
               <span>still more</span>
               <ul>
                    <li>Another &gt;ul&lt;, oh my!</li>
                    <li>...</li>
               </ul>
          </div>
      </li>
   </ul>

aunque en realidad salió así:

<ul id="matchMe" type="square">           <li>stuff...</li>           <li>more stuff</li>           <li>               <div>                    <span>still more</span>                    <ul>                         <li>Another &gt;ul&lt;, oh my!</li>                         <li>...</li>                    </ul>               </div>           </li>        </ul>

Por último, disfruté mucho el artículo de Jeff Atwood: Analizando Html The Cthulhu Way. Curiosamente, cita la respuesta a esta pregunta que actualmente tiene más de 4k votos.


261



Sugiero usar QueryPath para analizar XML y HTML en PHP. Básicamente tiene la misma sintaxis que jQuery, solo que está en el lado del servidor.


255



Si bien las respuestas que no puede analizar HTML con expresiones regulares son correctas, no se aplican aquí. El OP solo quiere analizar una etiqueta HTML con expresiones regulares, y eso es algo que se puede hacer con una expresión regular.

La expresión regular sugerida es incorrecta, sin embargo:

<([a-z]+) *[^/]*?>

Si agrega algo a la expresión regular, retrocediendo puede forzarse para que coincida con cosas tontas como <a >>, [^/] es muy permisivo También tenga en cuenta que <space>*[^/]* es redundante, porque el [^/]* también puede unir espacios.

Mi sugerencia sería

<([a-z]+)[^>]*(?<!/)>

Dónde (?<! ... ) es (en Perl regexes) el aspecto negativo detrás. Se lee "a <, luego una palabra, luego cualquier cosa que no sea a>, la última de las cuales puede no ser a /, seguida de>".

Tenga en cuenta que esto permite cosas como <a/ > (al igual que la expresión regular original), por lo que si desea algo más restrictivo, debe compilar una expresión regular para hacer coincidir los pares de atributos separados por espacios.


212