Сплит линия с Perl
У меня есть многострочные кредиты с пропуском нескольких запятых:
rendező: Joe Carnahan forgatókönyvíró: Brian Bloom, Michael Brandt, Skip Woods zeneszerző: Alan Silvestri operatőr: Mauro Fiore producer: Stephen J. Cannell, Jules Daly, Ridley Scott szereplő(k): Liam Neeson (John 'Hannibal' Smith ezredes) Bradley Cooper (Templeton 'Szépfiú' Peck hadnagy) szinkronhang: Gáti Oszkár (John 'Hannibal' (Smith magyar hangja)) Rajkai Zoltán (Templeton 'Faceman' Peck magyar hangja)
Это приводит к невозможности разделения строки запятыми:
$credits (split /, */, $line):
Я хочу разделить после запятой и, если не существует запятой между кредитами, разделить после первых кредитов (например):
rendező: Joe Carnahan
forgatókönyvíró: Brian Bloom
Michael Brandt
Skip Woods
zeneszerző: Alan Silvestri
operatőr: Mauro Fiore
producer: Stephen J. Cannell
Jules Daly
Ridley Scott
szereplő(k): Liam Neeson (John 'Hannibal' Smith ezredes)
Bradley Cooper (Templeton 'Szépfiú' Peck hadnagy)
szinkronhang: Gáti Oszkár (John 'Hannibal' (Smith magyar hangja))
Rajkai Zoltán (Templeton 'Faceman' Peck magyar hangja)
Спасибо
2 ответа
Таким образом, вы можете разделить запятую в большинстве случаев, но в остальном символ пробела, которому предшествует правая скобка. Это было бы:
/, |(?<=\)) /
Или, может быть (?) Более ясно:
/,[[:space:]]|(?<=\))[[:space:]]/
Символ "труба" создает дизъюнктивное совпадение между тем, что находится по обе стороны от него. Но есть также разбор ролей, и вся строка полна не-ascii символов.
Автор сценария:
use strict;
use warnings;
use utf8;
use Data::Dump 'dump';
my $big_string = q/rendező: ... hangja)/;
my @credits = map {
my ($title, $names) = /([[:alpha:]()]+): (.+)/;
my @names = split /,[[:space:]]|(?<=\))[[:space:]]/, $names;
my $credit = { $title => \@names };
} split / (?=[[:alpha:]()]+:)/, $big_string;
binmode STDOUT, ':utf8';
print dump \@credits;
Выход:
[
{ rendező => ["Joe Carnahan"] },
{
forgatókönyvíró => ["Brian Bloom", "Michael Brandt", "Skip Woods"],
},
{ zeneszerző => ["Alan Silvestri"] },
{ operatőr => ["Mauro Fiore"] },
{
producer => ["Stephen J. Cannell", "Jules Daly", "Ridley Scott"],
},
{
"szerepl\x{151}(k)" => [
"Liam Neeson (John 'Hannibal' Smith ezredes)",
"Bradley Cooper (Templeton 'Sz\xE9pfi\xFA' Peck hadnagy)",
],
},
{
szinkronhang => [
"G\xE1ti Oszk\xE1r (John 'Hannibal' (Smith magyar hangja))",
"Rajkai Zolt\xE1n (Templeton 'Faceman' Peck magyar hangja)",
],
},
]
Заметки:
- Массив hashrefs используется для сохранения порядка списка.
utf8
Прагма сделает[:alpha:]
построить utf8-осведомленный.- Учитывая Perl >= v5.10, The
utf8::all
Прагма может заменитьutf8
а также убрать необходимость звонить&binmode
до выхода. - Lookarounds (
(?=)
,(?<=)
и т. д.) может быть хитрым; см. perlre и это руководство для хорошей информации о них.
Я думаю, вы можете попытаться настроить регулярное выражение. Вы можете заменить любое "слово:" на "\ nword:" так же, как вы можете заменить "," на ",\n"
чтобы посмотреть регулярное выражение, проверьте эту страницу: http://www.troubleshooters.com/codecorn/littperl/perlreg.htm
2 руля должны быть примерно такими:
$newstr ~= ($str =~ tr/[a-zA-Z]+:/(\n)[a-Z]+:/);
это всего лишь предположение... не совсем известно о синтаксисе Perl