2012-10-04 5 views
17

Je n'arrive pas à trouver un moyen d'extraire tous les commentaires comme dans l'exemple suivant.Regex correspondant entre deux chaînes?

>>> import re 
>>> string = ''' 
... <!-- one 
... --> 
... <!-- two -- -- --> 
... <!-- three --> 
... ''' 
>>> m = re.findall ('<!--([^\(-->)]+)-->', string, re.MULTILINE) 
>>> m 
[' one \n', ' three '] 

bloc avec two -- -- ne correspond pas très probablement à cause du mauvais regex. Quelqu'un peut-il s'il vous plaît me diriger dans la bonne direction comment extraire les correspondances entre deux chaînes. Salut, j'ai testé ce que vous avez suggéré dans les commentaires .... voici une solution de travail avec peu de mise à jour.

>>> m = re.findall ('<!--(.*?)-->', string, re.MULTILINE) 
>>> m 
[' two -- -- ', ' three '] 
>>> m = re.findall ('<!--(.*\n?)-->', string, re.MULTILINE) 
>>> m 
[' one \n', ' two -- -- ', ' three '] 

merci!

+3

Tout ce qui se trouve entre [] est un seul caractère, donc (->) ne cherchera pas ce regroupement fait partie du problème ... –

+2

're.findall ('', string, re.DOTALL)' devrait faire. Vous n'avez pas besoin de '^ \ (->)' ici, parce que le point d'interrogation le rend non-gourmand. – BrtH

+0

Vous avez l'air de ne chercher que les mots? Si oui, qu'est-ce qui ne va pas avec 'm = re.findall ('[\ w] +', string, re.MULTILINE)'? De plus, string est un mauvais nom pour une chaîne, um. – Ben

Répondre

32

cela devrait faire l'affaire

m = re.findall ('<!--(.*?)-->', string, re.DOTALL) 
+0

merci pour la réponse rapide et exacte. –

+1

Vous n'avez pas besoin du drapeau MULTILINE. –

+0

@AlanMoore, merci d'avoir raison. Mise à jour de la réponse – iruvar

3

En général, il est impossible de faire de la correspondance arbitraire entre deux délimiteurs avec un regular grammar.

specifcally, si vous permettez l'imbrication,

<!-- how do you deal <!-- with nested --> comments? --> 

vous tomberez dans les questions. Ainsi, bien que vous puissiez résoudre ce problème spécifique avec une expression régulière, toute expression régulière que vous écrivez peut être interrompue par une autre imbrication étrange de commentaires. Pour analyser les commentaires arbitraires, vous devez passer à une méthode d'analyse context free grammars. Une méthode simple pour le faire est d'utiliser un pushdown automaton.

+1

Je ne pense pas que les commentaires imbriqués soient si communs. Kinda rejette le point de commenter si quelque chose à l'intérieur est traité? –

+1

Et il semble qu'ils ne sont pas possibles en HTML. http://stackoverflow.com/questions/442786/are-nested-html-comments-possible Je vais laisser ceci ici, parce que je pense qu'il est important de le reconnaître, mais je ne m'attends pas à des upvotes. – Wilduck

+1

Les machines à états finis ne peuvent pas analyser les grammaires contextuelles - vous pouvez utiliser des automates Pushdown. –

Questions connexes