Python regex to parse groups after specific labels

Viewed 44

I have a list of texts like this:

Something at the beginning
    
References
1. Ryff, C.D. (2014) Psychological Well-Being Revisited: Advances in the Science and Practice of Eudaimonia. 
2. Deci, E.L. & Ryan, R.M. (2002) Self-determination research: reflections and future directions. 
3. Acedo, F. J., & Casillas, J. C. (2005). Current paradigms in the international management field.
        
Other References
1. Tarelli, E. (2003), “How to transfer responsibilities from expatriates to local nationals”.
2. Riusala, K. and Suutari, V. (2004), “International knowledge transfers through expatriates”.
3. Wallace, J. (2001), “The benefits of mentoring for female lawyers”.

Something at the end
12. Wallace, J. (2001), “The benefits of mentoring for female lawyers”.
Something else at the end

'Other References' part is present in some texts, but not present in others. Also similar strings could appear anywhere in the texts.

I need regex to use in re.findall and return all strings after 'References' in a list of strings like this.

['Ryff, C.D. (2014) Psychological Well-Being Revisited: Advances in the Science and Practice of Eudaimonia.', 'Deci, E.L. & Ryan, R.M. (2002) Self-determination research: reflections and future directions.', 'Acedo, F. J., & Casillas, J. C. (2005). Current paradigms in the international management field.']

But ONLY after 'References' and NOT anywhere earlier or later in the text.

I have tried this regex

r = 'References\s*(\d+[.].*[.])'

But it returns only first string occurrence and I need all

Could anybody please suggest a better regex pattern?

2 Answers

You could use re.findall, twice. The strategy below is to first match all reference blocks as separate strings. We then join all such strings together, and then use re.findall to find all references.

inp = """Something at the beginning

References
1. Ryff, C.D. (2014) Psychological Well-Being Revisited: Advances in the Science and Practice of Eudaimonia. 
2. Deci, E.L. & Ryan, R.M. (2002) Self-determination research: reflections and future directions. 
3. Acedo, F. J., & Casillas, J. C. (2005). Current paradigms in the international management field.
    
Other References
1. Tarelli, E. (2003), “How to transfer responsibilities from expatriates to local nationals”.
2. Riusala, K. and Suutari, V. (2004), “International knowledge transfers through expatriates”.
3. Wallace, J. (2001), “The benefits of mentoring for female lawyers”.

Something at the end
12. Wallace, J. (2001), “The benefits of mentoring for female lawyers”.
Something else at the end"""

refs = re.findall(r'^References\n((?:\d+\.\s*.*?\n)+)', inp, flags=re.M)
data = ''.join(refs)
output = re.findall(r'\d+\.\s*(.*?)\n', data)
print(output)

This prints:

[
    'Ryff, C.D. (2014) Psychological Well-Being Revisited: Advances in the Science and Practice of Eudaimonia. ',
    'Deci, E.L. & Ryan, R.M. (2002) Self-determination research: reflections and future directions. ',
    'Acedo, F. J., & Casillas, J. C. (2005). Current paradigms in the international management field.'
]

This is an answer to the linked question, which is closed as a duplicate; so I can't answer there. That duplicate question is more an extension of this question, since it complicates the input.

Using as input example

text = """Something at the beginning

References 1. Ryff, C.D. (2014) Psychological Well-Being Revisited: Advances in the Science and Practice of Eudaimonia. Additional Fields. 2. Deci, E.L. & Ryan, R.M. (2002) Self-determination research: reflections and future directions. 3. Wallace, J. (2001), “The benefits of mentoring for female lawyers”. 315 – 326. DOI: doi.org/10.2224/sbp.2008.36.3.315 4. Acedo, F. J., & Casillas, J. C. (2005). Current paradigms in the international management field. Other References 1. Tarelli, E. (2003), “How to transfer responsibilities from expatriates to local nationals”.
2. Riusala, K. and Suutari, V. (2004), “International knowledge transfers through expatriates”.
3. Wallace, J. (2001), “The benefits of mentoring for female lawyers”.

Something at the end
12. Wallace, J. (2001), “The benefits of mentoring for female lawyers”.
Something else at the end"""

and working with the following assumptions:

  • reference sections are distinguished by the word "References" (with a capital "R"), possibly preceeded by another, capitalized, word (just one word; "Really Bad References" is excluded as a separator for now, though that is straightforward to adjust).
  • references in a section are separated by the following:
    one or more digits, followed by a period, followed by a space, followed by non-digit characters (letters, commas, &-signs etc), followed by an opening parenthesis (for the year).
  • only the first section, "References", is the one of interest (can probably be straightforwardly amended).

Then the following code can work:

# split the sections
pattern = r'[A-Z][a-z\s]+References'
sections = re.split(pattern, text, flags=re.M)

# split the individual references, by conditions as mentioned in point 2 above
pattern = r'\s*(\d+\.\s+\D+\()'
# The first section is blank (`''`), so `sections[1]` is 
# the first actual reference section, "References"
parts = re.split(, sections[1], flags=re.M)

# the split includes the part before the year, and the year + rest. 
# We need to concatenate those items for each reference. 
# Also here, the first group is blank, so skip that
refs = [part1 + part2 for part1, part2 in zip(parts[1::2], parts[2::2])]

# Show the result
for ref in refs:
    print(ref)

which yields

1. Ryff, C.D. (2014) Psychological Well-Being Revisited: Advances in the Science and Practice of Eudaimonia. Additional Fields.
2. Deci, E.L. & Ryan, R.M. (2002) Self-determination research: reflections and future directions.
3. Wallace, J. (2001), “The benefits of mentoring for female lawyers”. 315 – 326. DOI: doi.org/10.2224/sbp.2008.36.3.315
4. Acedo, F. J., & Casillas, J. C. (2005). Current paradigms in the international management field.
Related