Мне нужно преобразовать имя в формате Parisi, Kenneth в формат kparisi.
Кто-нибудь знает, как это сделать на Perl?
Вот некоторые образцы данных, которые не соответствуют норме:
Зеллеб, Чарльз Ф. ,, IV
Эйлт, Джон, IV
Уодс, Чарльз Р. ,, III
Велкт, Крейг П., младший
Эти конкретные имена должны заканчиваться как czelleb, jeilt, cwoods, cwelkt и т. д.
У меня есть еще одно условие, которое портит мое имя builder
О'Нил, Пол
до сих пор ответ Винко Врсаловича работает лучше всего, когда в смеси присутствуют странные / коррумпированные имена, но этот пример выше будет выглядеть как "pneil" ... черт возьми, ниже Иуды, если я не могу понять это между п и п


Пытаться:
$name =~ s/(\w+),\s(\w)/$2$1/;
$name = lc $name;
\w здесь соответствует буквенно-цифровому символу. Если вы хотите быть более конкретным, вы также можете использовать вместо него [a-z] и передать флаг i (без учета регистра):
$name =~ s/([a-z]+)\s([a-z])/$2$1/i;
Ой. Спасибо за исправление, Пол. Я действительно протестировал код перед публикацией, но почему-то остался доволен своим неправильным результатом. ;-)
Извините за это, но вы не Джон Скит. :-)
да, я только что проверил это тоже ... это выглядело близко, но я не получил товар
@ «Ты не Джон Скит» - представьте себе. Но, возможно, это я, и он создал вторую учетную запись, чтобы анонимно публиковать второстепенные решения, чтобы побороть скуку. ;-)
Я бы начал с фильтрации аномальных данных, чтобы у вас были только обычные имена. Тогда что-то вроде этого должно помочь
$t = "Parisi, Kenneth";
$t =~ s/(.+),\s*(.).*/\l$2\l$1/;
я наткнулся на контрольно-пропускной пункт «Марфи-Смулка, Мара» обозначается как «mmarphy-smulka», как вы думаете, я могу избавиться от «-» или просто использовать первую часть фамилии, исключая любые небуквенные символы
vinko@parrot:~$ cat genlogname.pl
use strict;
use warnings;
my @list;
push @list, "Zelleb, Charles F.,,IV";
push @list, "Eilt, John,, IV";
push @list, "Woods, Charles R.,,III";
push @list, "Welkt, Craig P.,,Jr.";
for my $name (@list) {
print gen_logname($name)."\n";
}
sub gen_logname {
my $n = shift;
#Filter out unneeded characters
$n =~ s/['-]//g;
#This regex will grab the lastname a comma, optionally a space (the
#optional space is my addition) and the first char of the name,
#which seems to satisfy your condition
$n =~ m/(\w+), ?(.)/;
return lc($2.$1);
}
vinko@parrot:~$ perl genlogname.pl czelleb jeilt cwoods cwelkt
почему я не получил уведомления обо всех ответах? У меня ушло много времени, и я задумался, почему до сих пор никто не ответил ... хе!
не знаю ... они пришли довольно быстро ... я разместил этот вопрос только 10 минут назад .... в любом случае спасибо за ввод, я думаю, что ответ Расмуссена пока работает нормально
эй, винко ... я вижу, что фамилии, такие как "О'Нил, Пэт" и "Паризи-Кэйд, Кеннет", входят как pneil и kcaid .... второй вариант хорош, но O'neil, Pat будет Лучше зайти как понейл
Вот это доработано. Если вам нужно отфильтровать больше символов, чем 'и - вы можете добавить их между [] под комментарием «отфильтровать ненужные символы»
Единственное, что меня беспокоит, так это то, что я разместил вопрос, очень похожий на этот, на Perl Monks, и получил бы больше помощи от SO, чем от Perl Monks по тому же вопросу (это было несколько месяцев назад).
Вот однострочное решение, предполагающее, что вы храните все имена в файле с именем «names» (по одному в каждой строке), и позже вы каким-то образом определите повторяющиеся имена.
cat names | perl -e 'while(<>) {/^\s*(\S*)?,\s*(\S)/; print lc "$2$1\n";}' | sed s/\'//g
Похоже, ваши входные данные разделены запятыми. Для меня самый простой способ сделать это - разбить на компоненты, а затем сгенерировать из них имена для входа:
while (<>) {
chomp;
my ($last, $first) = split /,/, lc $_;
$last =~ s/[^a-z]//g; # strip out nonletters
$first =~ s/[^a-z]//g; # strip out nonletters
my $logname = substr($first, 0, 1) . $last;
print $logname, "\n";
}
$rowfetch =~ s/['-]//g; #All chars inside the [ ] will be filtered out.
$rowfetch =~ m/(\w+), ?(.)/;
$rowfetch = lc($2.$1);
вот как я закончил использовать решение Винко Врсаловича ... это внутри цикла while, который проходит через результат запроса sql ... еще раз спасибо винко
Это должно делать то, что вам нужно
use strict;
use warnings;
use 5.010;
while ( <DATA> ) {
say abbreviate($_);
}
sub abbreviate {
for ( @_ ) {
s/[-']+//g;
tr/A-Z/a-z/;
tr/a-z/ /c;
return "$2$1" if /([a-z]+)\s+([a-z])/;
}
}
__DATA__
Zelleb, Charles F.,,IV
Eilt, John,, IV
Woods, Charles R.,,III
Welkt, Craig P.,,Jr.
O'Neil, Paul
czelleb
jeilt
cwoods
cwelkt
poneil
Конрад, у вас это было наоборот - это должна быть вся фамилия (которая идет первой), а затем первая инициальная (которая идет второй)