2009-06-05 8 views
2

Je suis supposé capturer tout à l'intérieur d'un tag et les lignes suivantes après, mais il est supposé s'arrêter la prochaine fois qu'il rencontre un crochet. Qu'est-ce que je fais mal?Mon regex en python n'est pas récursif correctement

import re #regex 

regex = re.compile(r""" 
     ^     # Must start in a newline first 
     \[\b(.*)\b\]   # Get what's enclosed in brackets 
     \n     # only capture bracket if a newline is next 
     (\b(?:.|\s)*(?!\[)) # should read: anyword that doesn't precede a bracket 
     """, re.MULTILINE | re.VERBOSE) 

haystack = """ 
[tab1] 
this is captured 
but this is suppose to be captured too! 
@[this should be taken though as this is in the content] 

[tab2] 
help me 
write a better RE 
""" 
m = regex.findall(haystack) 
print m 

ce que im essayant d'obtenir est:
[('tab1', « ceci est capturé \ nmais cela est supposé être capturé trop \ n @ [cela devrait être pris que comme cela! est dans le contenu] \ n », '[tab2]', 'aide-moi \ nwrite un meilleur RE \ n')]

modifier:

regex = re.compile(r""" 
      ^   # Must start in a newline first 
      \[(.*?)\] # Get what's enclosed in brackets 
      \n   # only capture bracket if a newline is next 
      ([^\[]*) # stop reading at opening bracket 
     """, re.MULTILINE | re.VERBOSE) 

cela semble fonctionner mais il coupe aussi les parenthèses insid e le contenu

Répondre

3

Python regex ne supporte pas la récursivité afaik.

EDIT: mais dans votre cas cela fonctionnerait:

regex = re.compile(r""" 
     ^   # Must start in a newline first 
     \[(.*?)\] # Get what's enclosed in brackets 
     \n   # only capture bracket if a newline is next 
     ([^\[]*) # stop reading at opening bracket 
    """, re.MULTILINE | re.VERBOSE) 

EDIT 2: oui, il ne fonctionne pas correctement.

import re 

regex = re.compile(r""" 
    (?:^|\n)\[    # tag's opening bracket 
     ([^\]\n]*)   # 1. text between brackets 
    \]\n     # tag's closing bracket 
    (.*?)     # 2. text between the tags 
    (?=\n\[[^\]\n]*\]\n|$) # until tag or end of string but don't consume it 
    """, re.DOTALL | re.VERBOSE) 

haystack = """[tag1] 
this is captured [not a tag[ 
but this is suppose to be captured too! 
[another non-tag 

[tag2] 
help me 
write a better RE[[[] 
""" 

print regex.findall(haystack) 

Je suis d'accord avec le viraptor. Regex sont cool mais vous ne pouvez pas vérifier votre fichier pour les erreurs avec eux. Un hybride peut-être? : P

tag_re = re.compile(r'^\[([^\]\n]*)\]$', re.MULTILINE) 
tags = list(tag_re.finditer(haystack)) 

result = {} 
for (mo1, mo2) in zip(tags[:-1], tags[1:]): 
    result[mo1.group(1)] = haystack[mo1.end(1)+1:mo2.start(1)-1].strip() 
result[mo2.group(1)] = haystack[mo2.end(1)+1:].strip() 

print result 

EDIT 3: C'est parce que ^ caractère signifie qu'à l'intérieur négatif correspondance [^squarebrackets]. Partout ailleurs cela signifie que le début de chaîne (ou début de ligne avec re.MULTILINE). Il n'y a pas de bon moyen de faire correspondre les chaînes négatives dans regex, seul le caractère.

+0

merci pour la réponse, je vois, je l'ai bien essayé le récursif (R?), Mais vous avez raison, il est pas vraiment travailler en python alors savez-vous un moyen pour moi de le faire afin que je puisse réaliser ce que je suis en train de faire? – cybervaldez

+0

Im ayant un problème, il semble s'arrêter quand il y a une parenthèse à l'intérieur du contenu aussi bien. Comment puis-je le faire afin qu'il s'arrête seulement quand il trouve un [crochet sur le début de la ligne seulement. [tab1] – cybervaldez

+0

Merci, cette question a été très instructive car beaucoup de détails et d'alternatives sont apparus. Je suis assez surpris de voir à quel point les choses sont vraiment différentes de votre première solution. Je n'ai pas l'idée de pourquoi ma solution n'a pas fonctionné: (^ [\ n \ [] *), n'est-ce pas lu pour arrêter quand il y a un [crochet après un retour à la ligne? pourquoi ça ne marche pas? c'est juste pour la matière à réflexion, votre réponse fonctionne parfaitement déjà. – cybervaldez

2

Est-ce que cela fait ce que vous voulez?

regex = re.compile(r""" 
     ^     # Must start in a newline first 
     \[\b(.*)\b\]   # Get what's enclosed in brackets 
     \n      # only capture bracket if a newline is next 
     ([^[]*) 
     """, re.MULTILINE | re.VERBOSE) 

Ceci donne une liste de tuples (un 2-tuple par correspondance). Si vous voulez un tuple aplati, vous pouvez écrire:

m = sum(regex.findall(haystack),()) 
+0

m = somme (regex.findall (haystack),()) merci pour le pourboire! – cybervaldez

3

Tout d'abord pourquoi une regex si vous essayez d'analyser? Comme vous pouvez le voir, vous ne pouvez pas trouver la source du problème vous-même, car regex ne donne aucun retour. De plus, vous n'avez aucune récursion dans cette RE.

Faites votre vie simple:

def ini_parse(src): 
    in_block = None 
    contents = {} 
    for line in src.split("\n"): 
     if line.startswith('[') and line.endswith(']'): 
     in_block = line[1:len(line)-1] 
     contents[in_block] = "" 
     elif in_block is not None: 
     contents[in_block] += line + "\n" 
     elif line.strip() != "": 
     raise Exception("content out of block") 
    return contents 

Vous obtenez une erreur de manipulation avec des exceptions et la capacité d'exécution de débogage comme un bonus. En conséquence, vous obtenez un dictionnaire et pouvez gérer les sections en double lors du traitement. Mon résultat:

{'tab2': 'help me\nwrite a better RE\n\n', 
'tab1': 'this is captured\nbut this is suppose to be captured too!\[email protected][this should be taken though as this is in the content]\n\n'} 

RE est beaucoup plus galvaudé de nos jours ...

+0

Oui, c'est ce qu'un ami m'a aussi suggéré mais je me suis dit que je devais faire regex car ça m'aiderait beaucoup pour de futures regexing (pardonnez le mot) et je viens de commencer à travailler avec regex donc je ne peux pas faire une analyse simple comme ce travail alors je ne vais probablement jamais apprendre mon chemin autour de regex. C'est pour ma compréhension de regex aussi bien et de l'apparence des choses j'ai vraiment besoin de l'apprendre. – cybervaldez

Questions connexes