2012-02-05 3 views
1

J'ai obtenu de l'aide avec cela plus tôt aujourd'hui mais je n'arrive pas à comprendre la dernière partie du problème que j'ai. Cette recherche regex renvoie toutes les correspondances dans le fichier ouvert de l'entrée. Ce que je dois faire est également de trouver quelle partie du fichier provient de la correspondance.python regex recherche d'ajouter une balise dans un fichier texte

Chaque section est ouverte et fermée avec une étiquette. Par exemple, l'un des tags s'ouvre avec <opera> et se termine par </opera>. Ce que je veux être en mesure de faire, c'est quand je trouve une correspondance que je veux soit revenir en arrière à la balise ouverte ou en avant à la balise de fermeture et inclure le contenu de la balise, dans ce cas "opéra" dans la sortie. Ma question est que je peux le faire avec un ajout à l'expression régulière ou y a-t-il un meilleur moyen? Voici le code que j'ai qui fonctionne très bien déjà:

text = open_file.read() 
#the test string for this code is "NNP^CC^NNP" 
grammarList = raw_input("Enter your grammar string: "); 

tags = grammarList.split("^") 
tags_pattern = r"\b" + r"\s+".join(r"(\w+)/{0}".format(tag) for tag in tags) + r"\b" 
# gives you r"\b(\w+)/NNP\s+(\w+)/CC\s+(\w+)/NNP\b" 

from re import findall 
print(findall(tags_pattern, text)) 

Répondre

0

Une façon de le faire serait de trouver toutes les occurrences de votre départ et balises de section de fin (disent qu'ils sont <opera> et </opera>), obtenir les indices, et comparez-les à chaque match de tags_pattern. Cela utilise finditer qui est comme findall mais renvoie aussi des index. Quelque chose comme:

startTags = re.finditer("<opera>",text) 
endTags = re.finditer("</opera>",text) 

matches = re.finditer(tags_pattern,text) 

# Now, [m.start() for m in matches] gives the starting index into `text`. 
# if <opera> starts at subindices 0, 1000, 2345 
# and you get a match starting at subindex 1100, 
# then it's in the 1000-2345 block. 
for m in matches: 
    # find first 
    sec = [i for i in xrange(len(startTags)) if i>startTags[i].start()] 
    if len(sec)=0: 
     print "err couldn't find it" 
    else: 
     sec = sec[0] 
     print "found in\n" + text[startTags[sec].start():endTags[sec].end()] 

(Remarque: vous pouvez obtenir le texte correspondant à m.group() Par défaut () a groupe 0 (chaîne entière), et vous pouvez utiliser m.group(i) pour le ième groupe de capture).

+0

Merci mathématique.coffee. Je pense que c'est une idée réalisable mais elle renvoie une erreur disant que le callable-itérateur n'a pas de len(). Je me sens comme si cela pouvait être plus facile d'utiliser les expressions régulières, non? J'ai le plus gros problème en ce moment, c'est la regex que j'ai en cours d'exécution que je ne comprends pas complètement. Ne pourrais-je pas simplement ajouter une chaîne de recherche à la regex qui demande ce qui est après le "" suivant? Cela me donnerait l'étiquette, non? Mon problème est que je ne sais pas comment faire cela. –

+0

Bien, vous pourriez avoir la regex étant une variation de ' (? =. *? Your_search_regex)' mais le problème est s'il peut y avoir plusieurs occurrences de votre tag regex dans chaque section, alors cela n'en prendra qu'un. –

0
from BeautifulSoup import BeautifulSoup 

tags = """stuff outside<opera>asdfljlaksdjf lkasjdfl kajsdlf kajsdf stuff 
<asdf>asdf</asdf></opera>stuff outside"""  

soup = BeautifulSoup(tags) 

soup.opera.text 
Out[22]: u'asdfljlaksdjf lkasjdfl kajsdlf kajsdf stuffasdf' 

str(soup.opera) 
Out[23]: '<opera>asdfljlaksdjf lkasjdfl kajsdlf kajsdf stuff 
<asdf>asdf</asdf></opera>' 
Questions connexes