Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > регулярные выражения


Автор: DESert 15.5.2006, 20:36
Доброе всем время суток!

Есть у меня такая задача, которую удалось при помощи долгих усилий осуществить на Си++. Добрые люди подсказали, что Perl с таким в одну строчку справится. Вчера начал изучение этого замечательного языка и понял, что действительно можно. 
Такая проблема: есть текстовые файл, кусок из него:

абдоминальный 8 п 1*а  abdominal
абдуктор 4 м 1а  abductor
абдукторный 4 п 1*а
абдукция 4 ж 7а  abduction
абелит 5 м 1а
аберрационный 9 п 1*а
аберрация 6 ж 7а  aberration comaII
абзац 4 м 5а  indent indentation indention paragraph rubric rubricate
абзацный 4 п 1*а-
абиетин 6 м 1а


нужно все слова из него переместить в другой файл при этом отредактировав каждую строчку, таким образом, чтобы в итоге каждая строка была вида:
словопробелчислопробелсловопробелчисло
т.е. требуется убрать из строки перевод русского на анг и всевозможные посторонние символы после второго числа
С регулярными выражениями я уже знаком, но не на таком уровне, чтобы с таким справится.... поэтому прошу вас  smile 
Помогите пожалуйста!  

Автор: arto 15.5.2006, 21:08
# perl -lne '@a = split "\\s+"; $a[3] =~ s|\D+||g; print join " ",@a[0,1,2,3];' test.in
абдоминальный 8 п 1
абдуктор 4 м 1
абдукторный 4 п 1
абдукция 4 ж 7
абелит 5 м 1
аберрационный 9 п 1
аберрация 6 ж 7
абзац 4 м 5
абзацный 4 п 1
абиетин 6 м 1
#  

Автор: DESert 15.5.2006, 21:54
ого  smile 
заранее извининяюсь за глупые вопросы и замечания...

 - но ведь здесь нет открытия файла из которого производится считывания, как я думаю что нет smile ....


 - что будет если изначально будет последовательность словопробелслово а дальше символы, которые надо убрать?

я знаю, что не первый кто просит всё ему тут разжевать, но 
заранее спасибо большое!  smile 
 

Автор: korob2001 16.5.2006, 15:03
Цитата(DESert @  15.5.2006,  18:54 Найти цитируемый пост)
 - но ведь здесь нет открытия файла из которого производится считывания, как я думаю что нет

Ну если с открытиями файлов, то в одну строку наверное не получится. ;))))
Цитата(DESert @  15.5.2006,  18:54 Найти цитируемый пост)
что будет если изначально будет последовательность словопробелслово а дальше символы, которые надо убрать?

Ну для этого нужна особая проверка, а это ещё строка кода. ;((((
Код
#!/usr/bin/perl -w
use strict;

open my $before, "<", "before.txt" or die "Can't open file 'before.txt': $!\n";
open my $after, ">", "after.txt" or die "Can't open file 'after.txt': $!\n";
flock($after,2);

     while (<$before>) {
              chomp;
              my(@words,@digest) = ();
              /(\d+)/ ? push(@digest, $1) : push(@words, $_) for ( (split(/\s+/))[0..3] );
              print $after join(" ", $words[0],$digest[0],$words[1],$digest[1]) . "\n";
     }

close($after) or die "Can't close file 'after.txt': $!\n";
close($before);

Этот код открывает файл, читает его построчно, разбивает его по пробелам и разделяет первые четыре элемента на два массива, слова и цифры ( последовательность не важна, главное, что бы в первых четырёх елементах строки были 2 слова и 2 цифры, как они будут расположены не имеет значения ). Слова в которых есть хоть одна цифра, будут восприняты как цифра, не цифровые символы будут отброшены.

Вот так выглядит файла before.txt
Код
абдоминальный 8 п 1*а  abdominal
абдуктор 4 м 1а  abductor
абдукторный 4 п 1*а
4 абдукция ж 7а  abduction
абелит 5 1а м
аберрационный 9 п 1*а
аберрация ж 6 7а  aberration comaII
4 5а абзац м  indent indentation indention paragraph rubric rubricate
абзацный 4 п 1*а-
абиетин 6 м 1а

Обрати внимание, что первые четыре элемента строки могут быть расположены и так:

слово слово число число
число число слово слово
слово число число слово
число слово слово число
число слово число слово
слово число слово число

После запуска программа создаст файл after.txt и он выглядит так:
Код
абдоминальный 8 п 1
абдуктор 4 м 1
абдукторный 4 п 1
абдукция 4 ж 7
абелит 5 м 1
аберрационный 9 п 1
аберрация 6 ж 7
абзац 4 м 5
абзацный 4 п 1
абиетин 6 м 1


ЗЫ: не знаю на сколько правильно я понял задачу, если что-то не так, то выложи код на C++, если он работает так как тебе нужно, то гораздо быстрее будет переписать его на Perl, чем гадать условия задачи. 

Автор: Kannabismus 16.5.2006, 17:22
Цитата

# perl -lne '@a = split "\\s+"; $a[3] =~ s|\D+||g; print join " ",@a[0,1,2,3];' test.in

Цитата
 - но ведь здесь нет открытия файла из которого производится считывания, как я думаю что нет


А test.in что по-вашему? 

Автор: arto 16.5.2006, 20:56
# perl -pnale '$_ = join " ",@F[0,1]' test.in
абдоминальный 8
абдуктор 4
абдукторный 4
абдукция 4
абелит 5
аберрационный 9
аберрация 6
абзац 4
абзацный 4
абиетин 6

#  

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)