Нужна помощь в разделении этой строки имен (пары имен и фамилий, разделенные запятыми и "и") - PullRequest
5 голосов
/ 28 августа 2011

Я использую Perl и мне нужно разделить строки с именами авторов, разделенных запятыми, а также последними "и". Имена формируются как имя и фамилия, выглядя так:

$string1 = "Joe Smith, Jason Jones, Jane Doe and Jack Jones";
$string2 = "Joe Smith, Jason Jones, Jane Doe, and Jack Jones";
$string3 = "Jane Doe and Joe Smith";
# Next line doesn't work because there is no comma between last two names
@data = split(/,/, $string1);

Я бы просто хотел разделить полные имена на элементы массива, как это делает split (), чтобы массив @data содержал, например:

@data[0]: "Joe Smith"
@data[1]: "Jason Jones"
@data[2]: "Jane Doe"
@data[3]: "Jack Jones"

Однако проблема в том, что между двумя последними именами в списках нет запятой. Любая помощь будет оценена.

Ответы [ 2 ]

10 голосов
/ 28 августа 2011

Вы можете использовать простое чередование в своем регулярном выражении для разделения:

my @parts = split(/\s*,\s*|\s+and\s+/, $string1);

Например:

$ perl -we 'my $string1 = "Joe Smith, Jason Jones, Jane Doe and Jack Jones";print join("\n",split(/\s*,\s*|\s+and\s+/, $string1)),"\n"'
Joe Smith
Jason Jones
Jane Doe
Jack Jones

$ perl -we 'my $string2 = "Jane Doe and Joe Smith";print join("\n",split(/\s*,\s*|\s+and\s+/, $string2)),"\n"'
Jane Doe
Joe Smith

Если вам также приходится иметь дело с оксфордской запятой (то есть "то, то и другое "), тогда вы могли бы использовать

my @parts = split(/\s*,\s*and\s+|\s*,\s*|\s+and\s+/, $string1);

Например:

$ perl -we 'my $s = "Joe Smith, Jason Jones, Jane Doe, and Jack Jones";print join("\n",split(/\s*,\s*and\s+|\s*,\s*|\s+and\s+/, $s)),"\n"'
Joe Smith
Jason Jones
Jane Doe
Jack Jones

$ perl -we 'my $s = "Joe Smith, Jason Jones, Jane Doe and Jack Jones";print join("\n",split(/\s*,\s*and\s+|\s*,\s*|\s+and\s+/, $s)),"\n"'
Joe Smith
Jason Jones
Jane Doe
Jack Jones

$ perl -we 'my $s = "Joe Smith and Jack Jones";print join("\n",split(/\s*,\s*and\s+|\s*,\s*|\s+and\s+/, $s)),"\n"'
Joe Smith
Jack Jones

Благодаря stackoverflowuser2010 за то, что отметили этот случай.

Вы захотите, чтобы \s*,\s*and\s+ в начале не давало другим ветвям чередования расщепляться на запятую или "и" сначала, этот порядок также гарантированно :

Альтернативы пробуются слева направо, поэтому первой найденной альтернативой, для которой соответствует все выражение, является выбранная.

4 голосов
/ 28 августа 2011

До split заменить and на ,:

$string1 =~ s{\s+and\s+}{,}g;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...