2010-08-08 6 views
0

Je vais avoir un problème correspondant à non HTML principalement des tags dans le texte, car les balises commence par &lt; et se termine par &gt; mais pas < et >. Donc, à la place <ref>xx</ref> j'ai &lt;ref&gt;xxx&lt;/ref&gt;. Ce que je dois faire est de supprimer tous ces tags, y compris leur contenu.Supprimer les tags spéciaux non HTML à partir du texte

Le problème est que certaines étiquettes peuvent avoir des attributs. J'ai trouvé une bonne réponse here mais il y a toujours un problème.

En supposant que je tag comme: <gallery src=sss>xxx</gallery> cette expression convient parfaitement:

@"<(?<Tag>\w+)[^>)]*>.*?</\k<Tag>>"

La réalité est tout à fait différent et tous les caractères spéciaux sont échappé, alors tag ressemble à: &lt;gallery src=sss&gt;xxx&lt;/gallery&gt;. Mon problème est de faire correspondre ce roi de tags. Jusqu'à présent, j'ai cette expression: @"\&lt\;(?<Tag>\w+)[^\&)]*\&gt\;.*?\&lt\;/\k<Tag>\&gt\;". Il correspond à des balises sans attributs, mais pas celle mentionnée ci-dessus. Qu'est-ce que je rate?

Le deuxième numéro correspond aux étiquettes {| |}, car elles peuvent être imbriquées. Pouvez-vous m'aider avec ça aussi? Cette expression ne fait pas l'affaire: @"\{\|(?:[^\|\}]|\{\|[^\|\}]*\|\})*\|\}"

Modifier: Pour clarifier le deuxième problème. Je dois faire correspondre les chaînes qui commencent par l'ouverture {| puis va du texte et se termine par |} tags. Cette structure peut être imbriquée, ainsi: {| xxx {| yyy |} xxx |} est autorisé. Je ne connais malheureusement pas le niveau d'imbrication maximum, mais disons que 1 convient à la plupart des cas.


Edit 2: Cette expression fonctionne pour mon 1er numéro @"\&lt\;(?<Tag>\w+).*?\&lt\;/\k<Tag>\&gt\;". J'ai remarqué qu'il échoue s'il y a une nouvelle marque de ligne entre l'ouverture et la fermeture des étiquettes.

Edit 3: Ce faire le travail avec la deuxième question: @"\{\|(?>(?!\{\||\|\}).|\{\|(?<N>)|\|\}(?<-N>))*(?(N)(?!))\|\}"

+0

Utilisez RegexOption.Singleline pour qu'il fonctionne avec les sauts de ligne. Il sera traité comme un caractère d'espace. –

Répondre

0

si vous avez un texte HTML échappé dans lequel vous voulez trouver des éléments? Pourquoi ne pas simplement l'oublier et utiliser le code que vous avez déjà? Vous pouvez utiliser HttpServerUtility.HtmlDecode() pour cela.

modifier: essayer ceci alors

string text = "PLAIN-TEXT&lt;gallery src=sss&gt;xxx&lt;/gallery&gt;PLAIN-TEXT"; 
while (text.IndexOf("&lt;") > -1) 
    text = Regex.Replace(text, "&lt;\\w+.*?&lt;/\\w+&gt;", ""); 
Console.WriteLine(text); 

dans le cas où il est source de confusion: la boucle est pour les balises imbriquées. Vous pouvez les gérer avec Regex mais cela devient compliqué.

+0

Parce que ces étiquettes seraient alors indiscernables des étiquettes réelles. – Aillyn

0

Cette regex devrait (en partie) le travail:

@"&lt;.+?&gt;(.*?)&lt;/.+?&gt;" 

Cela dit, regex n'est pas un outil approprié pour l'analyse syntaxique (X) HTML.Voici une meilleure solution:

  1. Ajouter un identifiant après l'&lt;, à savoir: BOGUS000: YourStr.Replace("&lt;", "&lt;BOGUS000")
  2. maintenant convertir la &lt; et %gt;-< et > utilisant HttpServerUtility.HtmlDecode()
  3. Parse le fichier en utilisant un analyseur XML
  4. Maintenant, vous savez tous les éléments qui ont un nom commençant par votre identifiant (ici BOGUS000) sont, eh bien, faux. Ils peuvent être enlevés.
  5. Profit! :)

Je ne suis pas sûr de comprendre votre deuxième problème.

+0

Cette expression échouera lorsque les balises seront imbriquées. – Ventus

+1

non, il ne suffit pas de tous les supprimer, mais depuis ". *?" veillera à ce que seul le tag le plus interne soit apparié, vous pouvez simplement l'exécuter plusieurs fois jusqu'à ce qu'il n'en reste plus. –

+1

@Ventus Regex n'est pas un outil approprié pour analyser (X) HTML, il arrive que ce soit la même chose, mais avec des balises d'ouverture et de fermeture différentes. Tu fais ce que tu peux. – Aillyn

0

ajouter RegexOptions.Singleline à l'appel Regex.Replace() (oui je sais, il se sent en arrière) pour résoudre le problème avec balise couvrant plusieurs lignes ne correspondant pas.

Deuxième question: En quoi le problème n'est-il pas exactement le même? La regex vous est donnée - il suffit de substituer les chaînes de délimitation et fait.

+0

le second n'est pas le même que le premier. La première était: ' contenu', mais la seconde est '{| contenu |} '. Le problème est que la seconde peut aussi ressembler à ça: '{| contenu {| contenu imbriqué |} {| un autre contenu imbriqué |} content |} '. Pour moi, c'est totalement différent du premier. – Ventus

+0

Non, c'est pareil. Vous avez une goutte de texte qui peut contenir des choses comme «texte [séquence d'ouverture] autre texte [séquence d'ouverture] plus de texte [séquence de fermeture] et encore plus de texte [séquence de fermeture] texte encore» La séquence d'ouverture '[séquence de fermeture]' varie, mais l'algorithme pour les résoudre est exactement le même. –

Questions connexes