删除perl中作者姓名中的姓名缩写

时间:2017-03-17 14:10:32

标签: regex perl

我想从名单列表中仅删除姓名缩写:

输入:

Bland-Hawthorn, J., van S\"{u}tterlin Breugel, W., Gillingham, P.R., \& Baldray, I.K.
Bettonvil, F.C.M., Hammerschlag, R.H., S\"{u}tterlin, P., et al.
Puschmann, K.G., Kneer, F., Seelemann, T., \& Wittmann, A.D.
Ramsay, J.V., Norton, D.G., \& Mugridge, E.G.V.  
Rutten, R.J.  2007 

输出:

Bland-Hawthorn, van S\"{u}tterlin Breugel, Gillingham, \& Baldray,
Bettonvil, Hammerschlag, S\"{u}tterlin, et al.
Puschmann, Kneer, Seelemann, \& Wittmann
Ramsay, Norton, \& Mugridge
Rutten

My Regex:

$str=~s/[^A-Z]([A-Z])\.?\s+/ /g for(0..5);
$str=~s/\s([A-Z])\.([A-Z])\.?\,?/ /g;
$str=~s/\,\s*([A-Z])\.\,/,/g; 

我认为有不同的方法来实现输出。无论如何,我的正则表达式是一个非常低的等级来获得输出。

任何人都可以帮助我找到一个模块,或者如果我们发现de van der,就可以找到复杂名称不同的正则表达式模式。

提前致谢。

2 个答案:

答案 0 :(得分:3)

以下脚本似乎适用于您的示例数据:

#!/usr/bin/env perl

use strict;
use warnings;

my @surnames;

while (my $authors = <DATA>) {
    $authors =~ /\S/ or last;
    $authors =~ s/\s+\z//;
    my @authors = split qr{\.,\s+(?:\Q\&\E\s+)?}, $authors;
    push @surnames, author_list_to_string( [ map /^([^,]+)/, @authors ] );
}

print "'$_'\n" for @surnames;

sub author_list_to_string {
    my $author_list = shift;

    if ( $author_list->[-1] eq 'et al.' ) {
        return join(', ', @$author_list);
    }

    if (@$author_list == 1) {
        return $author_list->[0];
    }

    if (@$author_list == 2) {
        return join(', \& ', @$author_list);
    }

    return join(', \& ',
        join(', ', @{$author_list}[0 .. ($#$author_list - 1)]),
        $author_list->[-1]
    );
}

__DATA__
Bland-Hawthorn, J., van S\"{u}tterlin Breugel, W., Gillingham, P.R., \& Baldray, I.K.
Bettonvil, F.C.M., Hammerschlag, R.H., S\"{u}tterlin, P., et al.
Puschmann, K.G., Kneer, F., Seelemann, T., \& Wittmann, A.D.
Ramsay, J.V., Norton, D.G., \& Mugridge, E.G.V.
Rutten, R.J.  2007

如果您的需求更复杂,您可以使用Lingua::EN::NameParse

答案 1 :(得分:1)

以下正则表达式应该这样做......

(?:[A-Z]\.){1,3},?

参见 regex demo / explanation

perl demo

$str = 'Bland-Hawthorn, J., van S\\"{u}tterlin Breugel, W., Gillingham, P.R., \\& Baldray, I.K.
Bettonvil, F.C.M., Hammerschlag, R.H., S\\"{u}tterlin, P., et al.
Puschmann, K.G., Kneer, F., Seelemann, T., \\& Wittmann, A.D.
Ramsay, J.V., Norton, D.G., \\& Mugridge, E.G.V.  
Rutten, R.J.  2007 ';
$regex = qr/(?:[A-Z]\.){1,3},?/p;
$subst = '';
$result = $str =~ s/$regex/$subst/rg;
print "$result";