Perl Array Вопрос - PullRequest
       24

Perl Array Вопрос

3 голосов
/ 21 декабря 2009

Никогда не занимался программированием - на работе брали на себя работу с данными из карточек с комментариями. До сих пор используя perl, у меня есть база данных, чтобы правильно помещать ежедневные комментарии в массив. Каждый комментарий - это одна строка текста в базе данных, поэтому я просто разбил массив на разрыв строки.

my @comments = split("\n", $c_data);

И да, это мое первое программирование, которое заняло у меня слишком много времени, чтобы понять.

На данный момент мне нужно организовать эти элементы массива (это то, что я должен назвать их?) В их собственные отдельные скаляры на основе прописных слов (это поведение базы данных, которая в какой-то момент была повреждена).

Пример того, как выглядят два элемента массива:

print "$comments[0]\n";
This dining experience was GOOD blah blah blah.

или

print "$comments[1]\n";
Overall this was a BAD time and me and my blah blah.

Эти "хорошие", "плохие" или "лучшие" уже прописаны в базе данных, из которой получены данные.

Какой самый простой способ в Perl получить эти строки в скаляры из массива на основе этих заглавных слов?

Ответы [ 6 ]

3 голосов
/ 21 декабря 2009

Подумайте хеш-таблицу , когда вы хотите сгруппировать данные по произвольным строковым ключам. В этом случае у вас есть массив хороших комментариев и массив плохих комментариев. Что если бы у вас был массив SO-SO комментариев? Стратегия, основанная на наличии переменных массива @good, @bad, @soso, быстро ломается.

У вас есть несколько путей, прежде чем вы сможете полностью понять код ниже:

#!/usr/bin/perl

use strict; use warnings;

use Regex::PreSuf;

my %comments;

my @types = qw( GOOD BAD ); # DRY
my $types_re = presuf @types;

while ( my $comment = <DATA> ) {
    chomp $comment;
    last unless $comment =~ /\S/;

    # capturing match in list context returns captured strings
    my ($type) = ( $comment =~ /($types_re)/ );
    push @{ $comments{$type} }, $comment;
}

for my $type ( @types ) {
    print "$type comments:\n";

    for my $comment ( @{ $comments{$type} } ) {
        print $comment, "\n";
    }
}

__DATA__
This dining experience was GOOD blah blah blah.
Overall this was a BAD time and me and my blah blah.
3 голосов
/ 21 декабря 2009

Если я вас правильно понял, вы хотите объединить элементы массива, которые соответствуют определенному слову. Вы можете сделать это так:

my @bad_comments = grep { /\bBAD\b/ } @comments;
my @good_comments = grep { /\bGOOD\b/ } @comments;

Таким образом, все «хорошие» и «плохие» комментарии попадают в каждый отдельный массив.

Теперь, если вам нужно объединить их в скаляр, вы бы хотели join их (напротив split):

my $bad_comments  = join "\n", grep { /\bBAD\b/ } @comments;
my $good_comments = join "\n", grep { /\bGOOD\b/ } @comments;
1 голос
/ 21 декабря 2009

Я бы сохранил все ваши комментарии в структуре данных хеш-массивов, ключом будет ваше заглавное слово. Вот общее решение для захвата любого заглавного слова (при условии, что только одно на комментарий), а не только ХОРОШО и ПЛОХО:

use strict;
use warnings;

my @comments = <DATA>;
chomp @comments;

my %data;
for (@comments) {
    my $cap;    
    for (split) {
        $cap = $_ if /^[A-Z]+$/;
    }
    if ($cap) { push @{ $data{$cap} }, $_ }
}
use Data::Dumper; print Dumper(\%data);

__DATA__
This is GOOD stuff
Here's some BAD stuff.
More of the GOOD junk.
Nothing here.

Вот вывод:

$VAR1 = {
          'BAD' => [
                     'Here\'s some BAD stuff.'
                   ],
          'GOOD' => [
                      'This is GOOD stuff',
                      'More of the GOOD junk.'
                    ]
        };
1 голос
/ 21 декабря 2009

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

if ($comments[$i] =~ /GOOD/) {
    # good comment
}

или более обычно

if ($comments[$i] =~ /\b([A-Z]{2,})\b/) {
    print "Comment: $1\n";
}

Здесь \ b означает границу слова, () используется для извлечения захваченного текста, [AZ] представляет группу заглавных символов - заглавные буквы, {2,} означает, что должно быть 2 или более символов, определенных предыдущим класс.

0 голосов
/ 21 декабря 2009

Не уверен, что вы подразумеваете под "организовать" и "на основе".

Если вы хотите создать список любых заглавных слов, каждое из которых содержит список строк, содержащих это слово (аналогично решению toolic , вы можете сделать это:

my %CAPS = ();

map {
    my ($word) = /(\b[A-Z]+\b)/;
    push( @{ $CAPS{$word} }, $_)
} @comments;

Это построит отображение СЛОВ на вещей , и вещей в этом случае будут списками строк.

И вы можете ссылаться на эти списки как $ CAPS {'GOOD'} или $ CAPS {'BAD'}, или $ CAPS { независимо от }.

0 голосов
/ 21 декабря 2009

На мой взгляд, вам лучше всего создать какую-нибудь базу данных на диске ( SQLite ?), В которой комментарии и тип будут храниться как отдельные данные.

Затем используйте одно из других опубликованных решений, чтобы импортировать в него существующие данные.

Единственная проблема здесь в том, что вам нужно изучить уровень DBI в Perl и немного SQL, чтобы использовать SQLite с Perl.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...