2010-07-06 6 views
1

Je dois analyser writeln("test"); à partir d'une chaîne.
J'utilisais (?<type>writeln)\((?<args>[^\)]*)\); comme regex, mais ce n'est pas parfait, si vous essayez d'analyser writeln("heloo :)"); ou quelque chose de similaire, la regex ne l'analysera pas (à cause du ') dans les guillemets). Existe-t-il un moyen d'enregistrer cela puisque le ')' est dans les guillemets, l'expression rationnelle devrait l'ignorer, et chercher le prochain ')'?Problème de complexe regex

Merci,
Max

Répondre

1

Ce qui suit correspond modèles comme writeln("hello :) \"world\"!");

string regex = "(?<type>writeln)\\(\"(?<args>(\\\\\"|[^\"])*)\"\\);";

Je suppose cela ne concerne que des arguments simples.

1

Vous avez rencontré le genre de problème que vous obtenez en utilisant des expressions rationnelles pour analyser des langues non régulières.

Cela dit, essayez:

(?<type>writeln)\((?<args>("[^"]*"|))\); 

Ce n'est pas parfait, mais rien ne sera. Pourquoi ne pas écrire un peu d'analyseur pour cela?

+0

Cela contourne l'exemple ci-dessus, mais pas le cas où vous avez une citation échappée: 'writeln (" hello \ "world \" ");'. Alors oui, comme vous l'avez dit, regex n'est pas une excellente solution pour cela. Si vous faites beaucoup d'analyse, utilisez un analyseur et une grammaire appropriés. –

2

Faites simplement une boucle sur les caractères et disposez d'une machine à états simple pour analyser.

Ce type de problème est difficile à faire dans les expressions régulières car le problème (grammaire) n'est pas régulier. Recherchez sur parsing HTML with regex en SO;)

MAIS: Si vous contrôlez votre entrée dans une certaine mesure, alors vous pourriez être en mesure de sortir avec regexes. Voir d'autres réponses ici pour "assez bon" façons de le faire.

Cela se résume essentiellement à:

  1. décider à quelle profondeur le trou du lapin (combien « récursivité » vous souhaitez simuler)
  2. créer une regex autre (branche) pour chaque récursion
  3. tirez vos yeux la prochaine fois que vous avez besoin de changer regex

Je le fais tout le temps. Et je me déteste pour ça!