2010-12-01 2 views
7

J'essaie de créer une expression régulière pour capturer des citations dans le texte.Expression régulière pour la reconnaissance de citations dans le texte

est ici quelques exemples de phrases de citations dans le texte:

  1. ... et les résultats rapportés dans (et al Nièvre, 2007.) n'étaient pas représentatifs ...

  2. ... deux systèmes ont utilisé une approche de chaîne de Markov (Sagae et Tsujii 2007).

  3. Nièvre (2007) ont montré que ...

  4. ... pour la fixation et les dépendances d'étiquetage (Chen et al, 2007;. Dredze et al., 2007).

Actuellement, l'expression régulière que j'ai est

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

Ce qui correspond à des exemples 1-3, mais pas l'exemple 4. Comment puis-je modifier cela pour capturer l'exemple 4?

Merci!

Répondre

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

\((.+?)\) doit capturer tous les

4

Je me sers quelque chose comme ça à cette fin ces derniers temps:

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

Lors de l'exécution, il produit:

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

Tout ce dont vous avez besoin est d'insérer un motif qui correspond à zéro ou plusieurs occurrences de votre motif pour une citation, eceded par un point-virgule. Conceptuellement, c'est: \(cite(; cite)*\).

Le motif est: \(\D*\d{4}(;\D*\d{4})*\).

1

Ceci est ma solution, en C++ avec boost regex. Il aide quelqu'un l'espoir :-)

#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

bâtiment sur Tex's answer, j'ai écrit un script Python très simple appelé Overcite à faire pour un ami (fin du semestre, paresseux vous le référencement savoir comment il est). C'est open source et MIT sous licence Bitbucket.

Il couvre quelques cas de plus que Tex qui pourraient être utiles (voir le fichier de test), y compris les esperluettes et les références avec des numéros de page. L'ensemble du script est essentiellement:

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) 
Questions connexes