Как использовать Perl для анализа указанного форматированного текста с помощью регулярных выражений? - PullRequest
1 голос
/ 21 июля 2010

Аннотация вопроса:

как разбить текстовый файл на два "хеша" в Perl.Один из пар ключ-значение, взятый из части (X = Y), другой из части (X: Y)?

1=9  
2=2  
3=1  
4=6  
2:1  
3:1  
4:1  
1:2
1:3  
1:4  
3:4  
3:2

они хранятся в одном файле и только символ между двумя цифрамиобозначает разницу.

=====================================================================================

Я только что потратил около 30я изучал Perl в течение последнего семестра и сумел закончить свое задание по Perl «головой, спеша, некрасиво».

Только что получил мой результат для этого раздела как 7/10, честно говоря, яменя это не устраивает, особенно потому, что это напоминает мою плохую память о попытке использовать Регулярное выражение для работы с отформатированными данными, это правило выглядит следующим образом:

1= (the last digit in your student ID,or one if this digit is zero)  
2= (the second last digit in your student ID,or one if this digit is zero)
3= (the third last digit in your student ID, or one if this digit is zero)
4= (the forth last digit in your student ID, or one if this digit is zero)

2:1 
3:1  
4:1  
1:2  
1:3  
1:4  
2:3 (if the last digit in your student ID is between 0 and 4) OR
    3:4 (if the last digit in your student ID is between 5 and 9)
3:2 (if the second last digit in your student ID is between 0 and 4) OR
    4:3 (if the second last digit in your student ID is between 5 and 9)

An example of the above configuration file: if your student ID is 10926029, it has to be:

1=9  
2=2  
3=1  
4=6  
2:1  
3:1  
4:1  
1:2
1:3  
1:4  
3:4  
3:2

Задание касалось вычисления Pagerank, алгоритм которогоупростил, поэтому я придумал ответ на эту часть за 5 минут.Тем не менее, именно часть анализа текста заняла у меня кучу времени.

Первая часть текста (Page = Pagerank) обозначает страницы и соответствующие им страничные ранги.

Вторая часть (FromNode: ToNode) обозначает направление ссылки между двумя страницами.

Для лучшего понимания перейдите на мой веб-сайт и проверьте файл требований и мой сценарий Perl здесь

В сценарии есть массивные комментарии, поэтому я считаю, что совсем нетрудно увидеть, насколько глупым я был в своем решении: (

Если вы все еще на этой странице, позвольте мне объяснить, почемуЯ задаю этот вопрос здесь, в SO:

Я получил только «Результат 7/10» без комментариев от универа.

Iя не учусь в университете, я учусь для себя.

Итак, я надеюсь, что Perl-гуру могут, по крайней мере, направить меня в правильном направлении к решению этой проблемы. Мое глупое решение было своего рода «общим»и вероятно будет работать в Java, C # и т. д. Я СуЭто даже не близко к природе Perl.

И, если возможно, пожалуйста, дайте мне знать уровень решения, как мне нужно пройти через "Изучение Perl ==> Программирование на Perl ==> MasterPerl ", чтобы попасть туда:)

Спасибо за любые подсказки и предложения заранее.

Редактировать 1:

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

Ответы [ 2 ]

3 голосов
/ 21 июля 2010

Это то, что вы имеете в виду? Регулярное выражение в основном имеет три группы захвата (обозначенные () s). Он должен захватывать одну цифру, затем либо = или : (это группа захвата, охватывающая класс символов [], который соответствует любому символу внутри него), а затем еще одну единственную цифру.

my ( %assign, %colon );

while (<DATA>) {
    chomp;                     
    my ($l, $c, $r) = $_ =~ m/(\d)([=:])(\d)/;

    if    ( q{=} eq $c ) { $assign{$l} = $r; }
    elsif ( q{:} eq $c ) { $colon{$l}  = $r; }
}        

__DATA__
1=9  
2=2  
3=1  
4=6  
2:1  
3:1  
4:1  
1:2
1:3  
1:4  
3:4  
3:2

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

1 голос
/ 21 июля 2010

Что ж, если вы не хотите проверять какие-либо ограничения на файл данных, вы можете легко проанализировать эти данные. Основная проблема заключается в выборе подходящей структуры для хранения ваших данных.

use strict;
use warnings;

use IO::File;

my $file_path = shift;  # Take file from command line

my %page_rank;
my %links;

my $fh = IO::File->new( $file_path, '<' )
    or die "Error opening $file_path - $!\n";

while ( my $line = $fh->readline ) {
    chomp $line;

    next unless $line =~ /^(\d+)([=:])(\d+)$/; # skip invalid lines

    my $page      = $1;
    my $delimiter = $2; 
    my $value     = $3;


    if( $delimiter eq '=' ) {

        $page_rank{$page} = $value;
    }
    elsif( $delimiter eq ':' ) {

        $links{$page} = [] unless exists $links{$page};

        push @{ $links{$page} }, $value;
    }

}

use Data::Dumper;
print Dumper \%page_rank;
print Dumper \%links;

Основным отличием этого кода от кода Педро Силвы является то, что мой код более многословен, и он также правильно обрабатывает несколько ссылок с одной страницы. Например, мой код сохраняет все значения для ссылок со страницы 1. Код Педро отбрасывает все, кроме последнего.

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