2012-02-05 73 views
1

今天早些时候我得到了一些帮助,但我无法弄清楚我遇到的问题的最后部分。该正则表达式搜索从输入中返回打开文件中的所有匹配项。我需要做的也是找到匹配来自哪个文件的哪一部分。python正则表达式搜索除了解析文本文件中的标签

每个部分用标签打开和关闭。例如,其中一个标签以<opera>打开,并以</opera>结束。我希望能够做到的是当我找到一个匹配时,我想要返回到开放标签或转发到关闭标签并包含标签的内容,在这种情况下,输出中的“opera”。我的问题是我可以用正则表达式的补充来做到这一点,还是有更好的方法?这里是我的代码,伟大的作品已经:

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)) 

回答

0

一种方式做到这一点是要找到你的开始和结束部分标签的所有匹配(说他们是<opera></opera>),得到的指数,并将它们与tags_pattern的每个匹配项进行比较。这使用finditer这就像findall但也返回索引。喜欢的东西:

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()] 

(注:你可以用m.group()默认()得到匹配的文本具有组0(即整个字符串),你可以使用m.group(i)第i个捕获组)。

+0

Thanks thankscoffee.coffee。我认为这是一个可行的想法,但它返回一个错误,说明可调用迭代器没有len()。我觉得只是使用正则表达式可能更容易,不是吗?我现在最糟糕的问题是我运行的正则表达式,我不完全理解。难道我不只是添加一个搜索字符串的正则表达式,要求什么是在下一个“”之前?那会给我这个标签,不是吗?我的问题是我不知道如何做到这一点。 – 2012-02-05 13:29:27

+0

好吧,你可能会得到一个'(?=。*?your_search_regex)'的一些变体,但问题是如果在每个部分中可以有多个标签正则表达式出现,那么这只会选择一个。 – 2012-02-05 23:21:42

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>'