Skipping over a regex pattern contained within the pattern I'm looking for

Viewed 26

I'm parsing Pandoc-markdown files that contain footnotes starting with ^[ and ending with ], some of which contain embedded []. For example:

...
to explain how the feature came to be as it is, so you can use generics more
effectively.^[Angelika Langer's [Java Generics FAQ](
www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html) as well as her other
writings (together with Klaus Kreft) were invaluable during the preparation of
this chapter.]
...

The simple approach of (in Python):

re.compile(r"\^\[.+?\]", flags=re.DOTALL)

Gets stopped at the first ] and thus doesn't capture the whole footnote. Is there a way to pass over the nested [] clause?

1 Answers

You can do that with the PyPi regex module using a subroutine, you just need to be careful when setting the group boundaries:

import regex
text = r"""...
to explain how the feature came to be as it is, so you can use generics more
effectively.^[Angelika Langer's [Java Generics FAQ](
www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html) as well as her other
writings (together with Klaus Kreft) were invaluable during the preparation of
this chapter.]
..."""
print( [x.group(1) for x in regex.finditer(r'\^(\[(?:[^][]++|(?1))*])', text)] )

Output:

["[Angelika Langer's [Java Generics FAQ](\nwww.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html) as well as her other\nwritings (together with Klaus Kreft) were invaluable during the preparation of\nthis chapter.]"]

See the Python demo and the regex demo. Details:

  • \^ - ^ char
  • (\[(?:[^][]++|(?1))*]) - Group 1:
    • \[ - a [ char
    • (?:[^][]++|(?1))* - 0 or more occurrences of:
      • [^][]++ - one or more chars other than ] and [
      • | - or
      • (?1) - Group 1 pattern
  • ] - a ] char.
Related