捕获标签的最后一次出现
我的文本格式是这样的:
<Story>
<Sentence id="1"> some text </Sentence>
<Sentence id="2"> some text </Sentence>
<Sentence id="3"> some text </Sentence>
我的任务是在最后一个 </Sentence>
后面插入一个结束标签 </Story>
。在文本中,每个 </Sentence>
后面都有三个空格。我尝试用正则表达式 </Sentence>(?!.*<Sentence)
来捕捉最后一个 </Sentence>
,并且也用了 re.DOTALL 选项。但是它没有成功。
我实际使用的代码是:
line = re.sub(re.compile('</Sentence>(?!.*<Sentence)',re.DOTALL),'</Sentence></Story>',line)
请帮帮我。谢谢。
4 个回答
0
为什么不把所有的(或者说有多少个)<Sentence>
元素都匹配出来,然后用一个组引用把它们放回去呢?
re.sub(r'(?:(\r?\n) *<Sentence.*?</Sentence> *)+',
r'$0$1</Story>',
line)
1
你真的应该使用像BeautifulSoup这样的解析器来完成这个任务。BeautifulSoup可以处理那些格式很糟糕的HTML/XML,并试图把它们变得正确。你的代码可以这样写(我假设在你错误的Story
标签前后还有其他标签,否则你应该参考David的评论):
from BeautifulSoup import BeautifulStoneSoup
html = '''
<Document>
<PrevTag></PrevTag>
<Story>
<Sentence id="1"> some text </Sentence>
<Sentence id="2"> some text </Sentence>
<Sentence id="3"> some text </Sentence>
<EndTag></EndTag>
</Document>
'''
# Parse the document:
soup = BeautifulStoneSoup(html)
看看BeautifulSoup是怎么解析的:
print soup.prettify()
#<document>
# <prevtag>
# </prevtag>
# <story>
# <sentence id="1">
# some text
# </sentence>
# <sentence id="2">
# some text
# </sentence>
# <sentence id="3">
# some text
# </sentence>
# <endtag>
# </endtag>
# </story>
#</document>
注意到BeautifulSoup在关闭它的外层标签(Document)之前就关闭了Story标签,所以你需要把关闭标签移动到最后一句话旁边。
# Find the last sentence:
last_sentence = soup.findAll('sentence')[-1]
# Find the Story tag:
story = soup.find('story')
# Move all tags after the last sentence outside the Story tag:
sib = last_sentence.nextSibling
while sib:
story.parent.append(sib.extract())
sib = last_sentence.nextSibling
print soup.prettify()
#<document>
# <prevtag>
# </prevtag>
# <story>
# <sentence id="1">
# some text
# </sentence>
# <sentence id="2">
# some text
# </sentence>
# <sentence id="3">
# some text
# </sentence>
# </story>
# <endtag>
# </endtag>
#</document>
最终的结果应该正是你想要的。请注意,这段代码假设文档中只有一个Story,如果不止一个,可能需要稍微修改一下。祝你好运!
3
如果同一段代码生成了整个文件,那就用一个专门处理XML的库来生成,这样所有的标签就会正确地嵌套在一起。如果不是,那就需要修正生成文件的代码,确保它是有效的XML。
正则表达式和XML不太搭配。