0

what a regular expression to extract the text between two values?

in:

<office:annotation office:name="__Annotation__45582_97049284">
</office:annotation>
    case 1 there can be an arbitrary text with any symbols
<office:annotation-end office:name="__Annotation__45582_97049284"/>

<office:annotation office:name="__Annotation__19324994_2345354">
</office:annotation>
    case 2there can be an arbitrary text with any symbols
<office:annotation-end office:name="__Annotation__19324994_2345354"/>

out:

list = [
'case 1 there can be an arbitrary text with any symbols',
'case 2 there can be an arbitrary text with any symbols',
]
Andrew Nodermann
  • 610
  • 8
  • 13

3 Answers3

3

It's better to use an XML parser, if you want a regex solution then try the below,

>>> str = """<office:annotation office:name="__Annotation__45582_97049284">
... </office:annotation>
...     case 1 there can be an arbitrary text with any symbols
... <office:annotation-end office:name="__Annotation__45582_97049284"/>
... 
... <office:annotation office:name="__Annotation__19324994_2345354">
... </office:annotation>
...     case 2there can be an arbitrary text with any symbols
... <office:annotation-end office:name="__Annotation__19324994_2345354"/>"""
>>> m = re.findall(r'<\/office:annotation>\s*(.*)(?=\n<office:annotation-end)', str)
>>> m
['case 1 there can be an arbitrary text with any symbols', 'case 2there can be an arbitrary text with any symbols']

OR

A better regex would be,

<\/office:annotation>([\w\W\s]*?)(?=\n?<office:annotation-end)
Avinash Raj
  • 172,303
  • 28
  • 230
  • 274
0

Since this is a namespaced XML document, you'll have to deal with those namespaces when selecting nodes. See this answer for details.

Here's how you would parse it using lxml and xpath expressions:

data.xml

<?xml version='1.0' encoding='UTF-8'?>
<document xmlns:office="http://www.example.org/office">

    <office:annotation office:name="__Annotation__45582_97049284">
    </office:annotation>
        case 1 there can be an arbitrary text with any symbols
    <office:annotation-end office:name="__Annotation__45582_97049284"/>

    <office:annotation office:name="__Annotation__19324994_2345354">
    </office:annotation>
        case 2there can be an arbitrary text with any symbols
    <office:annotation-end office:name="__Annotation__19324994_2345354"/>

</document>

parse.py

from lxml import etree

tree = etree.parse('data.xml')
root = tree.getroot()
nsmap = root.nsmap

annotations = root.xpath('//office:annotation', namespaces=nsmap)

comments = []
for annotation in annotations:
    comment = annotation.tail.strip()
    comments.append(comment)

print comments

Output:

['case 1 there can be an arbitrary text with any symbols',
 'case 2there can be an arbitrary text with any symbols']
Community
  • 1
  • 1
Lukas Graf
  • 30,317
  • 8
  • 77
  • 92
0
>>> regex = re.compile(r'</.+>\s*(.+)\s*<.+>')
>>> matched = re.findall(regex, text)
>>> print(matched)
['case 1 there can be an arbitrary text with any symbols', 'case 2there can be an arbitrary text with any symbols']

Edit: There we go. Bah.. these edit points.

kevr
  • 455
  • 4
  • 9