Perl 中的正则表达式捕获每段的前 n 行

regex in Perl to capture the first n lines of each paragraph

我使用 (\N+\n\N+\n\N+\n) 来捕获段落的前 3 行。如果我想捕获前 10 行,我是否必须重复这 10 次怎么办?有更短的方法吗?

以下面的文本文件为例:

Lorem ipsum fuga quisquam occaecati officiis eaque pariatur.
Sunt in ea harum optio ducimus.
Iusto est sunt fugiat voluptas aliquid.
MY HEADER LINE
Dolores provident non sapiente rerum quasi voluptatem repudiandae debitis.

Dolores sint aut aut itaque dolorum nulla non vel.
Nobis nostrum necessitatibus est quidem.
Veniam est aperiam consequatur est.
MY HEADER LINE
Sunt ut dolorem est iure est adipisci porro.
Qui occaecati quisquam provident et dicta aperiam.

使用 Perl,我可以轻松地将每个段落的第 4 行移动到该段落的顶部:

$ cat test | perl -00 -pe 's/(\N+\n\N+\n\N+\n)(\N+\n)//'
MY HEADER LINE
Lorem ipsum fuga quisquam occaecati officiis eaque pariatur.
Sunt in ea harum optio ducimus.
Iusto est sunt fugiat voluptas aliquid.
Dolores provident non sapiente rerum quasi voluptatem repudiandae debitis.

MY HEADER LINE
Dolores sint aut aut itaque dolorum nulla non vel.
Nobis nostrum necessitatibus est quidem.
Veniam est aperiam consequatur est.
Sunt ut dolorem est iure est adipisci porro.
Qui occaecati quisquam provident et dicta aperiam.

有没有办法用更短的东西替换 (\N+\n\N+\n\N+\n)

Perl 的正则表达式引擎支持常用的 {N} 运算符来选择精确的重复次数。为此,您需要再次对要匹配的部分进行分组(如果以后不想使用分组部分,请在分组前加上?:)):

例如,将 10 行组合在一起:

cat /tmp/test | perl -00 -pe 's/((?:\N+\n){10})(\N+\n)//'

文本可以按段落阅读,拆分成行数组,然后您可以根据需要操作行。

以下代码片段演示了这种方法。

use strict;
use warnings;
use feature 'say';

{
        local $/ = "\n\n";

        while( <DATA> ) {
                my @lines = split("\n",$_);
                say join("\n",@lines[3,0..2,4..$#lines]) . "\n";
        }
}


__DATA__
Lorem ipsum fuga quisquam occaecati officiis eaque pariatur.
Sunt in ea harum optio ducimus.
Iusto est sunt fugiat voluptas aliquid.
MY HEADER LINE
Dolores provident non sapiente rerum quasi voluptatem repudiandae debitis.

Dolores sint aut aut itaque dolorum nulla non vel.
Nobis nostrum necessitatibus est quidem.
Veniam est aperiam consequatur est.
MY HEADER LINE
Sunt ut dolorem est iure est adipisci porro.
Qui occaecati quisquam provident et dicta aperiam.

输出

Y HEADER LINE
Lorem ipsum fuga quisquam occaecati officiis eaque pariatur.
Sunt in ea harum optio ducimus.
Iusto est sunt fugiat voluptas aliquid.
Dolores provident non sapiente rerum quasi voluptatem repudiandae debitis.

MY HEADER LINE
Dolores sint aut aut itaque dolorum nulla non vel.
Nobis nostrum necessitatibus est quidem.
Veniam est aperiam consequatur est.
Sunt ut dolorem est iure est adipisci porro.
Qui occaecati quisquam provident et dicta aperiam.

参考: $/ - input record separator