Поиск и замена скрипта в заданной части текста - PullRequest
1 голос
/ 28 июля 2011

Я манипулирую текстовыми файлами и мне нужно создать Perl-скрипт для запуска замены поиска только по примечаниям определенной части текста (в данном случае глав), чтобы я мог преобразовать этот шаблон:

Chapter 1:1 text here(Note a) more text here(Note b)
2 text here(Note c) more text here(Note d)
3 text here(Note e) more text here(Note f)
4 text here(Note g) more text here(Note h)
Chapter 2:1 text here(Note i) more text here(Note j)
2 text here(Note k) more text here(Note l)
3 text here(Note m) more text here(Note n)
4 text here(Note o) more text here(Note p)
5 text here(Note q) more text here(Note r)
6 text here(Note s) more text here(Note t)

в это:

Chapter 1:1 text here(Note a) more text here(Note b)
2 text here(Note c) more text here(Note d)
3 text here(Note e) more text here(Note f)
4 text here(Note g) more text here(Note h)
Chapter 2:1 text here(Note a) more text here(Note b)
2 text here(Note c) more text here(Note d)
3 text here(Note e) more text here(Note f)
4 text here(Note g) more text here(Note h)
5 text here(Note i) more text here(Note j)
6 text here(Note k) more text here(Note l)

Другими словами, мне нужно установить «счетчик» каждой ноты на «а» в начале каждой новой главы.Следующее регулярное выражение соответствует каждой главе:

(?s)^\w{1,10} \d{1,3}:\d{1,3}.+?\(Note \w\).+?(?=\w{1,10} \d{1,3}:\d{1,3})

, и я попытался использовать цикл while, подобный этому:

my @notes = ('Note a', 'Note b', 'Note c', 'Note d');
$Count = a;
foreach my $Marker (@notes) {
    $_=~s/(\\(Note\\))[a-z]/"$1".$Count++/e;
}

Но я застрял и не могу придумать способ построитьсценарий таким образом, что он останавливается в каждом разделе главы, а затем начинается снова до конца.Может быть, я использую неправильный подход?

Что мне нужно сделать, чтобы применить поиск и замену только к каждой главе, как показано выше (т. Е. Первое регулярное выражение)?

Любая помощь будет оценена.Спасибо!

РЕДАКТИРОВАТЬ (30 июля)

Оба ответа работают отлично.Я проголосовал за первый как за мой любимый, потому что я лучше понимаю логику, но ОБА одинаково действительны.

Теперь, как следствие моего первого вопроса.Как я мог легко включить название главы и номер главы последовательно перед каждой строкой?Вот так:

Chapter 1:1 text here(Note a) more text here(Note b)
Chapter 1:2 text here(Note c) more text here(Note d)
Chapter 1:3 text here(Note e) more text here(Note f)
Chapter 1:4 text here(Note g) more text here(Note h)
Chapter 2:1 text here(Note a) more text here(Note b)
Chapter 2:2 text here(Note c) more text here(Note d)
Chapter 2:3 text here(Note e) more text here(Note f)
Chapter 2:4 text here(Note g) more text here(Note h)
Chapter 2:5 text here(Note i) more text here(Note j)
Chapter 2:6 text here(Note k) more text here(Note l)

Нужно ли использовать переменную и увеличивать ее или есть более простой подход?

Ответы [ 2 ]

3 голосов
/ 28 июля 2011

Вы должны разбить текст на главы и обработать их по отдельности.

# $book holds your text
my @chapters = split /^(?=Chapter\s+\d+:\d+)/m, $book;

for my $chap (@chapters) {
    my $cnt = 'a';
    $chap =~ s/(?<=\(Note )[a-z]/$cnt++/ge;
    print $chap;
}

Это будет работать для вашего примера.Вам просто нужно выяснить, как обрабатывать более 26 нот (аз).

РЕДАКТИРОВАТЬ: Вот как вы можете читать в тексте построчно и записать выходной файл:

open IN, 'infile.txt';
open OUT, '>', 'outfile.txt';

my $cnt;
for my $line (<IN>) {
    $cnt = 'a' if $line =~ /^Chapter\s+\d+:\d+/;
    $line =~ s/(?<=\(Note )[a-z]/$cnt++/ge;
    print OUT $line;
}
0 голосов
/ 29 июля 2011

Вы также можете сделать это без разбиения, как это:

s/^(chapter\s+\d+:\d+)|(\(note\s+)[a-z]+(?=\))/$a='a'if$1; $1?$1:$2.$a++/gime;

PS: не забудьте use strict; и use warnings;.


Полный пример, основанный на комментарии ОП:

use strict;
use warnings;

open my $fh, '<', '/Users/rgp/Desktop/Test.txt' or die "cant open file: $!";
my $content = do { local $/ = undef; <$fh> };
close $fh;

$content =~ s/^(chapter\s+\d+:\d+)|(\(note\s+)[a-z]+(?=\))/$a='a'if$1; $1?$1:$2.$a++/gime;

print "Result:\n";
print $content;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...