2010-08-06 5 views
0

Je chaîne suivante:Comment puis-je trouver un div HTML contient du texte spécifique après un préfixe de texte?

<div> text0 </div> prefix <div> text1 <strong>text2</strong> text3 </div> text4

et que vous voulez savoir qu'il contient text3 wether l'intérieur divs qui vont après le préfixe:

prefix<div>...text3...</div>

mais je ne sais pas comment ta faire regex pour cela, puisque je ne peux pas utiliser [^<]+ parce que div peut contenir strong tag à l'intérieur.

S'il vous plaît aider

EDIT:

  1. balises Div après préfixe sont guaranted à ne pas imbriquées
  2. Le langage est C#
  3. Texte4 est très longue, donc regex ne doit pas regarder après la fermeture div

EDIT2: Je ne veux pas utiliser l'analyseur html, il peut être facilement (et BEAUCOUP plus rapide) éd avec Regex. HTML il est simple: pas d'attributs dans les balises; pas de div de nidification. Et même quelques% de mauvaises réponses sont acceptables dans mon cas.

+7

Vous ne pouvez pas utiliser (de manière fiable) regex pour cela, car comme vous l'avez noté, les expressions régulières ne traitent pas des fonctionnalités non régulières du langage, telles que l'imbrication de HTML/etc. ** Vous devez utiliser un parseur DOM HTML - quelle langue essayez-vous de faire? ** –

+1

Vous voulez probablement apprendre à connaître jquery – naugtur

+1

Quelle langue? Différentes langues prennent en charge différentes fonctionnalités RegEx et elles ne sont pas identiques. Même si RegEx est la mauvaise solution, les recommandations d'une bonne solution exigent la connaissance de la langue que vous utilisez. – Oded

Répondre

0

ceci est mon nouveau regex:

prefix<div>([^<]*<(?!/div>))*[^<]*text3([^<]*<(?!/div>))*[^<]*</div>

semble bien fonctionner.

0

Pour C# + HtmlAgilityPack vous pouvez faire quelque chose comme:

InputString = Regex.Replace(InputString,"^(?:[^<]+?|<[^>]*>)*?prefix",""); 

HtmlDocument doc = new HtmlDocument(); 

doc.LoadHtml(InputString); 

HtmlNode node = doc.DocumentNode.SelectSingleNode("//div[contains('text3')]"); 

La suppression du préfixe est toujours pas une bonne façon de traiter avec elle. Idéalement, vous feriez quelque chose comme utiliser HtmlAgilityPack pour trouver où prefix se produit dans le DOM, traduisez cela pour fournir la position dans la chaîne, puis faites une sous-chaîne (pos, len) (ou équivalent) pour ne regarder que le texte pertinent (vous peut également éviter de regarder text4 en utilisant une méthode similaire). J'ai peur de ne pas pouvoir tout traduire en code pour le moment. J'espère que quelqu'un d'autre peut aider là-bas.


(réponse originale, avant que les détails supplémentaires fournis)
Voici une solution JavaScript + jQuery:

var InputString = '<div>text0 </div> prefix <div>text1 <strong>text2</strong> text3 </div> text4'; 

InputString = InputString.replace(/^.*?prefix/,''); 

var MatchingDivs = jQuery('div:contains(text3)','<div>'+InputString+'</div>') 

console.log(MatchingDivs.get()); 

Cela rend l'utilisation de la capacité de jQuery d'accepter un context as second argument (bien qu'il semble ceci doit être enveloppé dans des étiquettes div pour fonctionner réellement).

+0

Diviser par 'prefix' et ensuite essayer d'analyser l'une des sous-chaînes résultantes pourrait également entraîner des erreurs d'analyse si le préfixe se produit dans une balise . (Je n'ai pas utilisé jQuery, donc, je ne sais pas comment ça se comporterait dans une telle situation.) – David

+0

Ouais, ce morceau n'est certainement pas génial, mais mon cerveau n'est pas assez éveillé pour trouver un bon solution pour cela. :(Je l'ai amélioré légèrement en passant à un remplacement si. –

2

Si vous désactivez l'option "gourmand", vous devriez pouvoir utiliser quelque chose comme prefix<div>.*text3.*</div>. (Si le <div> est autorisé à avoir des attributs, utilisez plutôt prefix<div[^>]*>.*text3.*</div>.)

De nombreuses améliorations pourraient être apportées à ce afin de tenir compte de l'espacement inhabituel, > s entre guillemets, </div> entre guillemets, etc.

Les modèles comme prefix<div>...<div></div>text3</div> seraient plus difficiles. Vous devrez peut-être capturer toutes les occurrences de la balise div afin de pouvoir compter le nombre de balises div ouvertes à un moment donné.

EDIT: Oups, la désactivation de l'option gourmande ne donnera pas toujours le bon résultat, même dans des exemples autres que celui ci-dessus. Probablement mieux juste pour capturer toutes les occurrences de l'étiquette div et aller à partir de là. Comme noté ci-dessus par Peter, HTML n'est pas un regular language et donc vous ne pouvez pas utiliser des expressions régulières pour faire tout ce que vous pourriez vouloir avec.

Questions connexes