regex 用于识别文本中引用的正则表达式

siotufzp  于 2022-11-26  发布在  其他
关注(0)|答案(7)|浏览(150)

我试图创建一个正则表达式来捕获文本中的引用。
下面是一些文中引用的例句:
1.... (Nivre等人,2007) 中报告的结果不具有代表性...
1....两个系统使用了马尔可夫链方法 (Sagae和Tsujii 2007)

  1. Nivre (2007) 表明......
    1....用于附加和标记依赖项 (Chen等人,2007; Dredze等人,2007年)
    目前,我拥有的正则表达式是
\(\D*\d\d\d\d\)

它与示例1-3匹配,但与示例4不匹配。如何修改它以捕获示例4?
谢谢你!

wd2eg0qa

wd2eg0qa1#

我最近一直在用这样的东西来实现这个目的:

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

运行时,它将生成:

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

8nuwlpux2#

\((.+?)\)应该会撷取所有这些项目

m3eecexj

m3eecexj3#

基于Tex's answer,我为一个朋友写了一个非常简单的Python脚本,叫做Overcite(学期末,懒引用,你知道是怎么回事)。
它涵盖了比Tex更多的情况,这可能会有帮助(参见测试文件),包括与号和页码引用。整个脚本基本上是:

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)
btxsgosb

btxsgosb4#

/\(\D*\d\d\d\d(?:;\D*\d\d\d\d)*\)/
3hvapo4f

3hvapo4f5#

您所需要的只是插入一个模式,该模式与引用的模式匹配零次或多次,前面加一个分号。\(cite(; cite)*\) .
模式为:\(\D*\d{4}(;\D*\d{4})*\) .

rbl8hiat

rbl8hiat6#

这是我的解决方案,在C++中使用boost regex。希望它对某人有帮助:-)

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

qrjkbowd7#

到目前为止,这一条对我很有效:

\s\([^(]*?\d{4}.*?\)

根据你想要达到的目的,你可能需要删除前导白色(\s)。我把它放在这里是因为我想删除捕获的引文,如果我不包括空格,我会在引文前面的单词和后面的标点符号之间留下一个空格。
它包含问题中提到的所有示例(请参见https://regex101.com/r/BwBVif/1)。

相关问题