2010-12-01 4 views
7

Ich versuche, einen regulären Ausdruck zu erstellen, um In-Text-Zitate zu erfassen.Regulärer Ausdruck zum Erkennen von In-Text-Zitaten

Hier ein paar Beispiel Sätze Zitate im Text:

  1. ... und die berichteten Ergebnisse in (Nivre et al., 2007) waren nicht repräsentativ ...

  2. ... zwei Systeme verwendeten einen Markov-Kettenansatz (Sagae und Tsujii 2007).

  3. Nivre (2007) zeigte, dass ...

  4. ... zur Befestigung und Kennzeichnung Abhängigkeiten (Chen et al, 2007;. Dredze et al., 2007).

Derzeit ist der reguläre Ausdruck, den ich habe, ist

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

Welche Beispiele 1-3 entspricht, aber nicht Beispiel 4. Wie kann ich dieses Beispiel 4 zu erfassen ändern?

Danke!

Antwort

2
/\(\D*\d\d\d\d(?:;\D*\d\d\d\d)*\)/ 
1

\((.+?)\) sollten alle von ihnen erfassen

4

Ich habe in letzter Zeit zu diesem Zweck so etwas wie dies unter Verwendung von:

#!/usr/bin/env perl 

use 5.010; 
use utf8; 
use strict; 
use autodie; 
use warnings qw< FATAL all >; 
use open qw< :std IO :utf8 >; 

my $citation_rx = qr{ 
    \((?: 
     \s* 

     # optional author list 
     (?: 
      # has to start capitalized 
      \p{Uppercase_Letter}   

      # then have a lower case letter, or maybe an apostrophe 
      (?= [\p{Lowercase_Letter}\p{Quotation_Mark}]) 

      # before a run of letters and admissible punctuation 
      [\p{Alphabetic}\p{Dash_Punctuation}\p{Quotation_Mark}\s,.] + 

     ) ? # hook if and only if you want the authors to be optional!! 

     # a reasonable year 
     \b (18|19|20) \d\d 

     # citation series suffix, up to a six-parter 
     [a-f] ?   \b     

     # trailing semicolon to separate multiple citations 
     ; ? 
     \s* 
    ) + 
    \) 
}x; 

while (<DATA>) { 
    while (/$citation_rx/gp) { 
     say ${^MATCH}; 
    } 
} 

__END__ 
... and the reported results in (Nivré et al., 2007) were not representative ... 
... two systems used a Markov chain approach (Sagae and Tsujii 2007). 
Nivre (2007) showed that ... 
... for attaching and labelling dependencies (Chen et al., 2007; Dredze et al., 2007). 

Wenn er gestartet wird, produziert sie:

(Nivré et al., 2007) 
(Sagae and Tsujii 2007) 
(2007) 
(Chen et al., 2007; Dredze et al., 2007) 
1

Alles, was Sie brauchen, ist ein Muster einzufügen, das mit null oder mehr Vorkommen Ihres Musters für ein Zitat übereinstimmt, pr durch ein Semikolon ersetzt. Konzeptionell ist es: \(cite(; cite)*\).

Das Muster ist: \(\D*\d{4}(;\D*\d{4})*\).

1

Das ist meine Lösung, in C++ mit Boost Regex. Hoffe, es hilft jemand :-)

#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; 
} 
3

Aufbauend auf Tex's answer habe ich ein sehr einfaches Python-Skript Overcite tun dies für einen Freund namens geschrieben (Ende des Semesters, faul Referenzierung Sie wissen, wie es ist). Es ist Open Source und MIT lizenziert auf Bitbucket.

Es umfasst ein paar mehr Fälle als Tex, die hilfreich sein könnten (siehe Testdatei), einschließlich Et-Zeichen und Referenzen mit Seitenzahlen. Das ganze Skript ist im Grunde:

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) 
Verwandte Themen