Alex Rivera | Logout

Regular expression for recognizing in-text citations

Asked 2010-12-01T03:36:46.993
12

I'm trying to create a regular expression to capture in-text citations.

Here's a few example sentences of in-text citations:

  1. ... and the reported results in (Nivre et al., 2007) were not representative ...

  2. ... two systems used a Markov chain approach (Sagae and Tsujii 2007).

  3. Nivre (2007) showed that ...

  4. ... for attaching and labeling dependencies (Chen et al., 2007; Dredze et al., 2007).

Currently, the regular expression I have is

\(\D*\d\d\d\d\)

Which matches examples 1-3, but not example 4. How can I modify this to capture example 4?

Thanks!

Edit
Report

4 Answers

5

Building on Tex's answer, I've written a very simple Python script called Overcite to do this for a friend (end of semester, lazy referencing you know how it is). It's open source and MIT licensed on Bitbucket.

It covers a few more cases than Tex's which might be helpful (see the test file), including ampersands and references with page numbers. The whole script is basically:

author = "(?:[A-Z][A-Za-z'`-]+)"
etal = "(?:et al.?)"
additional = "(?:,? (?:(?:and |& )?" + author + "|" + etal + "))"
year_num = "(?:19|20)[0-9][0-9]"
page_num = "(?:, p.? [0-9]+)?"  # Always optional
year = "(?:, *"+year_num+page_num+"| *\("+year_num+page_num+"\))"
regex = "(" + author + additional+"*" + year + ")"

matches = re.findall(regex, text)
answered 2013-05-30T02:19:06.473
2
/\(\D*\d\d\d\d(?:;\D*\d\d\d\d)*\)/
answered 2010-12-01T03:39:00.633
2

All you need is to insert pattern that matches zero or more occurrences of your pattern for a citation, preceded by a semicolon. Conceptually, it's: \(cite(; cite)*\).

The pattern is: \(\D*\d{4}(;\D*\d{4})*\).

answered 2011-09-28T07:02:09.953
1

This is my solution, in C++ with boost regex. Hope it helps someone :-)

#include <string>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string_regex.hpp>
#include <boost/regex.h>

using namespace std;
using namespace boost;

int Section::countCitations() {
    string Personsname = "([A-Z][a-z'`-]+)"; // Apostrophes like in "D'Alembert" and hyphens like in "Flycht-Eriksson".
    string YearPattern = "(, *(19|20)[0-9][0-9]| ?\( *(19|20)[0-9][0-9]\))"; // Either Descartes, 1990 or Descartes (1990) are accepted.
    string etal = "( et al.?)"; // You may find this
    string andconj = Personsname + " and " + Personsname;
    string commaconj = Personsname + ", " + "(" + Personsname + "|"+"et al.?"+")"; // Some authors write citations like "A, B, et al. (1995)". The comma before the "et al" pattern is not rare.

    string totcit = Personsname+"?"+etal+"?"+"("+andconj+"|"+commaconj+")*"+etal+"?"+YearPattern; 
    // Matches the following cases:
    // Xig et al. (2004); 
    // D'Alembert, Rutherford et al (2008);
    // Gino, Nino and Rino, Pino (2007)
    // (2009)
    // Gino, et al. (2005)
    cout << totcit << endl;
    regex citationform(totcit);

    int count = 0;
    string_range citation;
    string running_text(text.begin(), text.end() );
    while ((citation = find_regex(running_text, citationform)) ) { // Getting the last one
        ++count;
        string temp(running_text.begin(), citation.end() );
        running_text = running_text.substr( temp.length()-1 );
    }
    return count;
}
answered 2012-05-10T12:01:07.063

Your Answer