Regex 搜索并替换文本给定部分上的脚本

Regex 搜索并替换文本给定部分上的脚本,regex,perl,replace,Regex,Perl,Replace,我正在处理文本文件,需要构建一个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

我正在处理文本文件,需要构建一个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)
换句话说,我需要在每个新章节的开头将每个音符的“计数器”设置为“a”。以下正则表达式与每个章节匹配:

(?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;
}
s/^(chapter\s+\d+:\d+)|(\(note\s+)[a-z]+(?=\))/$a='a'if$1; $1?$1:$2.$a++/gime;
但是我被卡住了,我想不出一种方法来构建一个脚本,让它在每一个章节都停止,然后重新开始,直到最后。也许我用错了方法

我需要做什么才能将搜索和替换仅应用于每个章节,如上图所示(即第一个正则表达式)

任何帮助都将不胜感激。 谢谢

编辑(7月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)

我是否需要使用一个变量并将其递增,还是有一种更简单的方法?

您应该将文本分为多个章节,并分别进行处理

# $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;
}
#$book保存您的文本
我的@chapters=split/^(?=Chapter\s+\d+:\d+)/m$book;
我的$chap(@章){
my$cnt='a';

$chap=~s/(?您也可以在不拆分的情况下执行此操作,如下所示:

my @notes = ('Note a', 'Note b', 'Note c', 'Note d');
$Count = a;
foreach my $Marker (@notes) {
    $_=~s/(\\(Note\\))[a-z]/"$1".$Count++/e;
}
s/^(chapter\s+\d+:\d+)|(\(note\s+)[a-z]+(?=\))/$a='a'if$1; $1?$1:$2.$a++/gime;
注意:不要忘记
使用严格;
使用警告;


基于OPs评论的完整示例:

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;
使用严格;
使用警告;

打开我的$fh,'发布问题时不需要添加

标记,只需按enter键换行即可。'z'在使用inc运算符.Perl magic时将增加为'aa'。mhyfritz,是的,没错,尽管我认为任何章节中都没有那么多注释。但是,我无法确定代码是否有效。我使用的是s设置IO文件,然后打印输出文件(或只打印$)。例如:打开(输入,“+您可以简单地使用shell重定向来打印文件。例如,
script.pl>output.txt
@TLP我希望从perl脚本本身内部进行打印。可以这样做吗?如果可以,怎么做?抱歉,现在是凌晨2点,无法清晰地思考……
打开我的$out,“>output.txt”或die$!
在循环之外,并将打印更改为
print$out$chap
。在Mac OS X(BBEdit)中使用您的代码似乎不适合我。我是否遗漏了什么?以下是完整的脚本:open(输入,“+这个正则表达式一次对整个文件起作用,我已经更新了答案,向您展示了如何使用它。非常感谢您费心回答。我发现这个脚本的问题是它只更改了第1章,但保留了第2章和后面的所有注释。我最初的问题是关于自动化w这是一个完整的过程,因为我处理的文件非常大,有数百章。它适用于所有章节,至少适用于您的示例数据。请参阅:You's very right.我使用了实际文档的一部分(根据您的演示示例)它成功了!但就我个人而言,我无法让你上面的完整示例起作用。正如我之前所说,我使用的是BBEdit。我在一个西方Mac OS Roman和经典Mac CR文件(即Test.txt)上运行脚本(西方Mac OS Roman和Unix LF)。到底出了什么问题?