2009-08-20 14 views

Respuesta

24

En su lugar, cámbielo a RegExOptions.Singleline y funcionará perfectamente. Cuando no está en el modo de línea única, el punto coincide con cualquier carácter, excepto nueva línea.

Tenga en cuenta que Singleline y Multiline no son mutuamente excluyentes. Ellos hacen dos cosas por separado. Para citar MSDN:

Modo multilínea. Cambia el significado de ^ y $ para que coincidan al principio y final, respectivamente, de cualquier línea, y no solo al principio y al final de la cadena completa.

Modo de línea única. Cambia el significado del punto (.) Por lo que coincide con cada carácter (en lugar de cada carácter excepto \ n).

Otras personas ya han sugerido el HTML Agility Pack. Simplemente sentí que debería tener una explicación sobre por qué su Regex no funcionaría :)

+4

+1 para responder la pregunta real. – womp

+0

Sí, funciona. Al principio no proporcioné el tercer parámetro y no funcionó, y pensé que RegExOptions.SingleLine está implícito, pero parece que Multiline está predeterminado. – MicMit

+1

Singleline y Multiline no son opuestos, no importa lo que los nombres parezcan implicar. Ambas opciones están desactivadas por defecto, y la configuración de una no tiene efecto en la otra. Singleline cambia el comportamiento del metacarácter de puntos, y Multiline cambia el comportamiento de los anclajes '^' y '$'. –

7

No utilice expresiones regulares para trabajar con los lenguajes de marcado: debe utilizar una herramienta mejor que esté diseñada para ese tipo de trabajo.

Use el Html Agiliy Pack en su lugar. Incluso encontré this article en el que un lector (llamado Simon Mourier) comenta con una función que utiliza la agilidad paquete de HTML a eliminar los comentarios de un documento:

Simon Mourier dijo:

Esta es una muestra código para eliminar comentarios:

static void Main(string[] args) 
{ 
    HtmlDocument doc = new HtmlDocument(); 
    doc.Load("filewithcomments.htm"); 
    doc.Save(Console.Out); // show before 
    RemoveComments(doc.DocumentNode); 
    doc.Save(Console.Out); // show after 
} 

static void RemoveComments(HtmlNode node) 
{ 
    if (!node.HasChildNodes) 
    { 
     return; 
    } 

    for (int i=0; i<node.ChildNodes.Count; i++) 
    { 
     if (node.ChildNodes[i].NodeType == HtmlNodeType.Comment) 
     { 
      node.ChildNodes.RemoveAt(i); 
      --i; 
     } 
    } 

    foreach (HtmlNode subNode in node.ChildNodes) 
    { 
     RemoveComments(subNode); 
    } 
} 
+0

Vi el comentario similar suyo en otro hilo.No estoy seguro de por qué debería usar una herramienta mejor para raspar Web ocasionalmente, extrayendo hrefs entre el marcador inicial y final en la página html, algunos de ellos comentados. – MicMit

+0

Andrew tiene razón. No puede analizar [X] [HT] ML con expresiones regulares, a menos que (a) sepa de antemano que se está utilizando un conjunto de contenido muy restringido y fijo o (b) no le molestan muchos errores en sus resultados. Los comentarios de análisis tienen menos probabilidades de romperse que los enlaces de análisis, ya que hay mucha más variabilidad en el formato de los enlaces, pero aún no es confiable. – bobince

+7

El ejemplo de código no funciona. No puede modificar los nodos mientras enumera en la colección –

0

Esta funciona para mí:

<!--(\n|.)*--> 

Pero creo que podría usar el documento XML normal para XML o HtmlAgilityPack para HTML. Altamente no se recomienda analizar el marcado mediante RegEx.

+2

Debe poner un cuantificador no codicioso en su multiplicador, es decir. '' Además, este problema puede resolverse simplemente agregando el indicador SingleLine que modifica. para aceptar nuevas líneas también ... –

+0

@Matthew. Sí. Estoy de acuerdo. En teoría, estás en lo correcto. Pero probé la bandera SingleLine y no cambia el resultado. También trabajo no codicioso y codicioso. Probado usando radsoftware.com.au/?from=RegexDesigner –

0

Este es el resultado superior de Google para eliminar comentarios a través de C#, y aquí está mi código HtmlAgilityPack para hacer esto.

 HtmlDocument doc = new HtmlDocument 
          { 
           OptionFixNestedTags = true, 
           OptionOutputAsXml = true 
          }; 
     doc.LoadHtml(str); 

     // Script comments from the document. 
     if (doc.DocumentNode != null) 
     { 
      HtmlNodeCollection nodes = doc.DocumentNode.SelectNodes("//comment()"); 
      if (nodes != null) 
      { 
       foreach (HtmlNode node in from cmt in nodes 
              where (cmt != null 
               && cmt.InnerText != null 
               && !cmt.InnerText.ToUpper().StartsWith("DOCTYPE")) 
               && cmt.ParentNode != null 
              select cmt) 
       { 
        node.ParentNode.RemoveChild(node); 
       } 
      } 
     } 

Esto funciona correctamente en los comentarios de desbroce, e ignora el tipo de documento que se considere como un comentario de HtmlAgilityPack.

Mientras que Regex funciona en condiciones controladas. Si está procesando HTML desde la web salvaje, le recomiendo usar HtmlAgilityPack. El HTML que está por ahí es muy impredecible, y regex se romperá.

Cuestiones relacionadas