Регулярное выражение не заменяет последнее совпадение - PullRequest
2 голосов
/ 24 августа 2011

У меня есть следующий текстовый макет:

Heading
Chapter 1:1 This is text
2 This is more text
3 This is more text
4 This is more text
5 This is more text
6 This is more text
7 This is more text
8 This is more text
9 This is more text
10 This is more text
11 This is more text
12 This is more text
13 This is more text
14 This is moret text 
15 This is more text
Heading    
Chapter 2:1 This is text
2 This is more text...

и я пытаюсь добавить первую ссылку на главу и последнюю в этой главе сразу после заголовка, написанную в скобках. Вот так:

Heading (Chapter 1:1-15)
Chapter 1:1 This is text
2 This is more text
3 This is more text
4 This is more text
5 This is more text
6 This is more text
7 This is more text
8 This is more text
9 This is more text
10 This is more text
11 This is more text
12 This is more text
13 This is more text
14 This is moret text 
15 This is more text

До сих пор я придумал это регулярное выражение:

~s/(?s)(Heading)\r(^\d*\w+\s*\d+:\d+|\d+:\d+)(.*?)(\d+)(.*?\r)(?=Heading)/\1 (\2-\4)\r\2\3\4\5/g;

но это захват первого номера сразу после главы 1: 1 (т. Е. «2», «Заголовок (глава 1: 1-2)») вместо последнего («15», как в «Заголовок (глава»). 1: 1-15) "). Может кто-нибудь сказать мне, что не так с регулярным выражением? Спасибо!

Ответы [ 2 ]

2 голосов
/ 24 августа 2011

Изменить для обновленного вопроса

Вот регулярное выражение с объяснением, которое решит вашу проблему. http://codepad.org/mSIYCw4R

~s/
((?:^|\n)Heading)   #Capture Heading into group 1.
                    #We can't use lookbehind because of (?:^|\n)
(?=                 #A lookahead, but don't capture.
  \nChapter\s       #Find the Chapter text.
  (\d+:\d+)         #Get the first chapter text. and store in group 2
  .*                #Capture the rest of the Chapter line.
  (?:\n(\d+).+)+    #Capture every chapter line.
                    #The last captured chapter number gets stored into group 3.
)
/$1 (Chapter $2-$3)/gx;
2 голосов
/ 24 августа 2011

Реализация комментария @ FMc может выглядеть примерно так:

#!/usr/bin/perl
use warnings;
use strict;

my $buffer = '';
while (<DATA>) {
    if (/^Heading \d+/) { # process previous buffer, and start new buffer
        process_buffer($buffer);
        $buffer = $_;
    }
    else { # add to buffer
        $buffer .= $_;
    }
}
process_buffer($buffer);   # don't forget last buffer's worth...


sub process_buffer {
    my($b) = @_;

    return unless length $b;  # don't bother with an unpopulated buffer

    my($last) = $b =~ /(\d+)\s.*$/;
    my($chap) = $b =~ /^(Chapter \d+:\d+)/m;
    $b =~ s/^(Heading \d+)/$1 ($chap-$last)/;

    print $b;
}

__DATA__
Heading 1
Chapter 1:1 This is text
2 This is more text
3 This is more text
4 This is more text
5 This is more text
6 This is more text
7 This is more text
8 This is more text
9 This is more text
10 This is more text
11 This is more text
12 This is more text
13 This is more text
14 This is moret text
15 This is more text
Heading 2
Chapter 2:1 This is text
2 This is more text...
3 This is more text
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...