2010-12-01 17 views
7

que estoy tratando de crear una expresión regular para capturar citas en el texto.Expresión regular para el reconocimiento de citas en el texto

He aquí algunas frases de ejemplo de citas en el texto:

  1. ... y los resultados reportados en (Nivre et al., 2007) no eran representativos ...

  2. ... dos sistemas utilizan un enfoque de cadena de Markov (Sagae y Tsujii 2007).

  3. Nivre (2007) mostraron que ...

  4. ... para unir y dependencias de etiquetado (Chen et al, 2007;. Dredze et al., 2007).

Actualmente, la expresión regular que tengo es

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

que coincide con los ejemplos 1-3, pero no el ejemplo 4. ¿Cómo se puede modificar esto para capturar el ejemplo 4?

Gracias!

Respuesta

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

\((.+?)\) debe capturar todos ellos

4

He estado usando algo como esto para ese propósito ultimamente:

#!/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). 

Cuando se ejecuta, produce:

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

Todo lo que necesita es insertar un patrón que coincida con cero o más ocurrencias de su patrón para una cita, pr eceded por un punto y coma. Conceptualmente, es: \(cite(; cite)*\).

El patrón es: \(\D*\d{4}(;\D*\d{4})*\).

1

Esta es mi solución, en C++ con impulso de expresiones regulares. Espero que ayuda a alguien :-)

#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

Basándose en Tex's answer, he escrito un script de Python muy sencillo llamado Overcite de hacer esto para un amigo (final del semestre, perezoso referencia Ya sabe lo que es). Es de código abierto y licencia MIT en Bitbucket.

Cubre unos cuantos casos que Tex de los cuales podrían ser útiles (véase el archivo de prueba), incluyendo los símbolos de unión y referencias con números de página. Todo el guión es básicamente:

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) 
Cuestiones relacionadas