用Perl/正则表达式删除字符串的前三行和后三行

6

我想构建一个正则表达式语句,以始终删除字符串的前三行和最后三行(中间部分可以是任意数量的行内容)。有没有干净的正则表达式方式来实现这个输出?(即始终从字符串中剥离出前3行和后3行,并保留可能有变量数量的中间部分行)

谢谢。

例如:

输入字符串:

"
1
2
3
<1...n # of lines content>
4
5
6
"

需要的输出字符串:

"<1..n # of lines content>"
3个回答

9
之前给出的解决方案真的非常复杂!所需要的只是:

s/^(?:.*\n){1,3}//;
s/(?:.*\n){1,3}\z//;

如果您希望接受结尾处缺少换行符,您可以使用以下方法:

s/\n?\z/\n/;
s/^(?:.*\n){1,3}//;
s/(?:.*\n){1,3}\z//;

或者

s/^(?:.*\n){1,3}//;
s/(?:.*\n){0,2}.*\n?\z//;

同意,这更加优美。我也喜欢\z,之前不知道它的存在。 - Johannes Petzold
太棒了,感谢大家的建议。这个方法非常有效...我之前还不知道\z呢。每天都有新的学习! - simbatish

4

这应该能解决问题。你可能需要根据输入字符串的换行格式将"\n"替换为"\r\n"。无论最后一行是否以换行符结尾,都可以使用此方法。

$input = '1
2
3
a
b
c
d
e
4
5
6';

$input =~ /^(?:.*\n){3} ((?:.*\n)*) (?:.*\n){2}(?:.+\n?|\n)$/x;

$output = $1;

print $output

输出:

a
b
c
d
e

-1
for($teststring)
{
    s/<.*?>//g;
    $teststring =~ s%^(.*[\n\r]+){3}([.\n\r]).([\n\r]+){3}$%$2%;
    print "Outputstring" . "\n" . $teststring . "\n";
}

你需要测试它是否在6行以下,等等。

这种方法的问题是,如果连续出现两行或更多行,如果没有它们的换行符,它们将为空,那么就会遇到麻烦。[\n\r]+可以匹配任意数量的换行符。最好先将行尾转换为本地操作系统的格式,而不是试图允许任何组合的\r和\n。 - DavidO
1
只需使用\R泛换行符,就不必再用\r和\n来玩游戏了,这会导致错误的出现。 - brian d foy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接