How to use regex to extract citation/reference context?

Viewed 35

I'm working with quotations/citations/references. In particular, given a text, I would like to extract citations and references, and a context for each of them. In my project, context is defined as the string of at most 10 characters to the left or right of a quote/citation/reference.

This is my code:

# some toy text
text = 'Once upon a time a cat says «gross!». A long story you can check here (ref. 11). People witnessed the scene [...]'

quoting_pattern = '\([^\(]*\)|„[^„]*"|<<.*>>|«[^«]*»|“[^“]*”|‹[^‹]*›|"[^"]*"|›[^›]*‹|»[^»]*«'
context_pattern = ".{0,100}(?:" + quoting_pattern + ").{0,100}"

# get all quotations
quotations = re.findall(r'{}'.format(quoting_pattern), text, re.DOTALL)
    
# get all contexts
contexts = re.findall(r'{}'.format(context_pattern), text, re.DOTALL)

for i, q in enumerate(quotations):
    print(q, contexts[i])

My expected result is this one:

"«gross!»", " cat says «gross!». A long s"
"(ref. 11)", "heck here (ref. 11)"

However, I got an error: IndexError: list index out of range.

Even if "«gross!»" and "(ref. 11)" are extracted in the 'quotations' variable and I'm able to extract the context for "«gross!»", I can't find any context for "(ref. 11)".

Why does this happen? How can I solve this issue? Thanks in advance

1 Answers

Try re.finditer. Match objects have .start() and .end() methods you can use to get context:

import re

text = "Once upon a time a cat says «gross!». A long story you can check here (ref. 11). People witnessed the scene [...]"
pat = re.compile(r"«[^»]*»|\"[^\"]*\"|\([^)]*\)")

for m in pat.finditer(text):
    ctx = text[max(m.start() - 10, 0) : min(m.end() + 10, len(text))]
    print(m.group(0), ctx)

Prints:

«gross!»  cat says «gross!». A long s
(ref. 11) heck here (ref. 11). People w
Related