0

I'm trying to pull some information (no recursion necessary) from a jsp page (malformed xml) similar to this:

<td>
<html:button ...></html:button>
<html:submit ...></html:submit></td>

And a regex:

<html:(button|submit|cancel)[\s\S]*?</html:(button|submit|cancel)>

re.findall() is giving me a list of tuples, like so:

[('button','button'),('button','button')]

Which I understand from the documentation is correct, but I'm looking to get something more like:

["<html:button ...>","<html:button ...>"]

What is the appropriate way to get the outcome I expect?

T.R.
  • 7,442
  • 6
  • 30
  • 34
  • http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454 ;) Well, maybe for this simple case regex might be appropriate ... but bobince's posting is worth reading all the same. – Johannes Charra Mar 03 '10 at 10:29
  • 2
    You don't want to continue trying to do this. You really must stop trying to write regular expressions for HTML and start using Beautiful Soup. http://www.crummy.com/software/BeautifulSoup/ – S.Lott Mar 03 '10 at 11:11
  • Thanks for the responses. I'll give everything a try tomorrow when I'm back at work. I will try to calm everyone's fears by mentioning that I'm not trying to do anything like match tags - because it's malformed xml, the tags just happen make convenient markers for the beginning and end of the information I need, they don't need to match at all. The lack of a closing end-bracket on the open tag in my example is actually intentional. – T.R. Mar 03 '10 at 12:31

2 Answers2

3

Aside from the fact that a regex probably isn't what you want to do this with, you want to put the bit you want in groups using parentheses. If you want everything up to the closing </html:whatever> tag, then you want something like this:

(<html:(button|submit|cancel)[\s\S]*?)</html:(button|submit|cancel)>

If you just want the <html:button> bit, use:

(<html:(button|submit|cancel)>)[\s\S]*?</html:(button|submit|cancel)>

e.g.

from

<html:button>foobar</html:submit>

you get:

('<html:button>', 'button', 'submit')

If you want to get the foobar from above, use:

(<html:(button|submit|cancel)>)([\s\S]*?)</html:(button|submit|cancel)>

to get:

('<html:button>', 'button', 'foobar', 'submit')

Note that it is not, in general, possible to match opening and closing tags (note that <html:button> is opened, and </html:submit> closes in the example above). If you need to do that, use a proper parser.

Dominic Rodger
  • 97,747
  • 36
  • 197
  • 212
1

Your (button|submit|cancel) getting capture, so add ?: in brackets like (?:

>>> re.findall('<html:(?:button|submit|cancel)[\s\S]*?</html:(?:button|submit|cancel)>',TheHTMLWhichShouldntParseWithRegex)
['<html:button ...></html:button>', '<html:submit ...></html:submit>']
YOU
  • 120,166
  • 34
  • 186
  • 219
  • This is actually exactly the information I was looking for. Thank you kindly. Though, I think I'll take S.Lott's suggestion and check out Beautiful Soup, as well. – T.R. Mar 04 '10 at 01:18