正则表达式不替换最后一次匹配

时间:2011-08-24 13:02:08

标签: regex perl

我有以下文字布局:

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:1(即“2”,“标题(第1章:1-2)”)之后抓住第一个数字,而不是最后一个(“标题”中的“15”) 1:1-15)“)。有人可以告诉我正则表达式有什么问题吗?谢谢!

2 个答案:

答案 0 :(得分:2)

@ 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

答案 1 :(得分:2)

修改以获取更新的问题

这是一个带有解释的正则表达式,可以解决您的问题。 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;