You really should use a parser like BeautifulSoup to do the job. BeautifulSoup can parse very incorrect HTML/XML and tries to make them look correct. Your code could look like this (I'm assuming you have some tags before and after your incorrect Story
tag, or else you would follow the advice from David's comment):
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)
Look how BeautifulSoup parsed it:
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>
Notice that BeautifulSoup closed the Story right before the closing of the tag that surrounded it (Document), so you have to move the closing tag next to the last sentence.
# 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>
The end result should be exactly what you wanted. Note that this code assumes there is only one Story in the document -- if not, it should be modified slightly. Good luck!