2010-07-27 4 views
4

.Net en utilisant l'expression rationnelleregex excluent correspondance de la capture

Je vais avoir un ensemble de données qui vient dans quelque chose comme ça

< Bunch o' Data Here > 

< est juste l'indicateur d'un nouvel enregistrement et > est la fin de l'enregistrement.

ces documents peuvent venir comme ça

< Dataset 1><Dataset 2 broken, no closing tag <dataset 3> 

ils pourraient aussi venir comme

< Dataset 1>Dataset 2 broken, no opening tag ><dataset 3> 

bien, je ne suis pas certain que ce dernier cas est possible, et je traverserai ce pont quand je dois.

J'essaie d'utiliser Regex pour diviser ceux-ci dans des dossiers en fonction de ce caractère de début et de fin, en fin de compte quelque chose comme ça

Match 1 = < Dataset 1> 
Match 2 = <Dataset 2 broken, no closing tag 
Match 3 = <Dataset 3> 

J'essaie de comprendre comment les groupes non-capture travail et Peut-être que ma compréhension est fausse.

<.*?(?:<|>) 

me obtient assez proche, je pense, sauf qu'il comprend le caractère d'ouverture de la 3ème série de données avec la capture du deuxième groupe. Je soupçonne également que ?: ne fait pas ce dont il a besoin et s'il le sort, il renvoie le même ensemble de correspondances (2).

Répondre

1

Je pense que je l'ai trouvé une solution plus simple

\<.*?(\>|(?=\<)|$) 

semble fonctionner. J'ai échappé aux <> marques de cohérence

EDIT: Ajout $ pour permettre un terminé à la fin de chaîne

+0

En utilisant cet ensemble de données: Dataset 2 cassé, pas d'étiquette d'ouverture> Dataset 2 cassé, pas de balise d'ouverture>

7

Il semble que vous l'ayez retourné. Vous voudrez utiliser ?: pour ne pas capturer un groupe, pas :?.

<.*?(?:<|>) 

Pour développer un peu: l'opérateur ? au sein d'un groupe de capture signifie que vous voulez faire quelque chose de spécial. Un : signifie ne pas capturer, mais il existe d'autres opérandes que vous pouvez donner au ? afin d'effectuer d'autres actions. Les plus courants sont anticipés (?=) et look-behind (?<), mais il y en a beaucoup d'autres.

Je viens également de réaliser la portée de ce que vous essayez de faire correspondre (au-delà du problème de non-capture). La langue des parens/brackets/etc appariés n'est pas régulière, donc - en supposant que je comprenne bien votre but - vous auriez besoin de créer une expression rationnelle étendue assez élaborée pour correspondre à ce que vous voulez. Il y a quelques autres questions SO à ce sujet, y compris this one qui a une discussion à ce sujet.

+0

merci. Désolé, c'était une faute de frappe dans mon cerveau. J'ai regardé mes tests et je l'ai eu correct. J'utilise cet opérateur correctement (je pense) et comme décrit ci-dessus avec les mêmes résultats. J'essaie aussi avec Negative Lookahead (?!) avec peu de succès, et je ne suis toujours pas sûr de ce que je pourrais manquer. – Beta033

+1

Je pense que vous pouvez également confondre l'idée de capturer le texte contre le consommer. Le?: Empêche le texte d'être capturé, ce qui signifie qu'il n'est stocké nulle part comme une référence distincte, mais le texte est toujours consommé. En d'autres termes, le texte correspondant au groupement?: Ne sera pas de nouveau mis en correspondance dans les expressions suivantes. Bien qu'il n'ait pas été capturé, il était déjà apparié (consommé). Cela aide-t-il? – eldarerathis

1

Que diriez-vous de quelque chose de simple comme ceci: < [^ <>] +> | [^ <>] +> | < [^ <>] +

+0

cela fonctionne très bien, cependant ces caractères de balise d'ouverture et de fermeture viendront de possibles utilisateurs et je voudrais minimiser la recherche et le remplacement fait pour construire la chaîne. – Beta033

+0

Regex ex = new Regex (String.Format ("{0} [^ {0} {1}] + {1} | [^ {0} {1}] + {1} | {0} [^ {0 } {1}] + "," <", "> ")); Quelque chose comme ca? –

1

Je pense que ce que vous cherchez est un préanalyse, pas un groupe non-capture. Mais changer simplement votre :? (sic) en ?= ne fera pas fonctionner correctement l'expression rationnelle.S'il n'y a jamais de texte entre une fermeture > et la prochaine <, essayez ceci:

<?[^<>]+>?(?=(?:<|$)) 

Il fonctionne si la fermeture > est manquant, mais pas si l'ouverture < est manquante.

Questions connexes