Perl Regex压缩多个换行符

时间:2011-02-05 17:56:08

标签: regex perl

我似乎无法弄清楚正确的语法,但我想要一个Perl正则表达式来查找一行中有两个或更多换行符并将它们压缩成只有两个换行符。

以下是我今天使用的似乎不起作用的内容:

$string =~ s/\n\n+/\n\n/g;

请让我知道我做错了什么以及我应该使用的正确的Perl正则表达式。

提前感谢您的帮助!

4 个答案:

答案 0 :(得分:7)

如果您使用的是Perl 5.10或更高版本,请尝试以下操作:

$string =~ s/(\R)(?:\h*\R)+/$1$1/g;

\R是通用行分隔符转义序列(ref),\h匹配任何水平空格字符(例如空格和TAB)(ref)。因此,这会将一个或多个空白行的任何序列转换为一个行。

现在大多数应用程序都很自由,他们认为是行分隔符;他们甚至会在同一文件中接受两种或更多种风格的分隔符的混合。另一方面,一些应用程序主动将所有行分隔符转换为一种首选样式。但有时你必须坚持一种特定的风格;这就是我捕获第一个\R匹配并将其用作替换的原因,而不是任意使用\n

请注意,这些特殊的转义序列在其他正则表达式中并不广泛支持。它们在PHP的最新版本中工作,\R似乎在Ruby 2.0中工作,但我找不到任何提及它的文档。 Ruby 1.9.2和2.0支持\h转义序列,但它匹配十六进制数字([0-9a-fA-F]),而不是水平空格。在大多数其他版本中,\R\h会抛出异常或分别与文字Rh匹配。

答案 1 :(得分:2)

这样做:

#!/usr/bin/env perl
use strict;
use warnings;
my $string;
{
   local $/=undef;
   $string =<DATA>;
} 
print "Before:\n$string\n============";

$string=~s/\n{2,}/\n\n/g;
print "After:\n$string\n\nBye Bye!";

__DATA__
Line 1
Line 2






Line 9
Line 10

Line 12



Line 16


Line 19

输出:

Before:
Line 1
Line 2






Line 9
Line 10

Line 12



Line 16


Line 19
============After:
Line 1
Line 2

Line 9
Line 10

Line 12

Line 16

Line 19

Perl还支持\R字符类以实现平台独立性。 See this SO link。那么你的正则表达式将是s/\R{2,}/\n\n/g;

答案 2 :(得分:0)

显示完整的示例。什么是$string

$ perl -E'my $s = qq{a\n\n\nb}; say "[$s]"; $s =~ s/\n\n+/\n\n/g; say "[$s]"'
[a


b]
[a

b]

答案 3 :(得分:0)

@btilly击中头部的钉子。我做了一个快速测试案例:

in

a

b




c

使用此代码:

my $line = join '', <>;
$line =~ s{\n\n+}{\n\n}g;
print $line;

它返回了预期的结果:

a

b

c

您可以通过更改记录分隔符(并避免使用正则表达式)来获得相同的结果:

{
    # change the Record Separator from "\n" to ""
    # treats multiple newlines as just one (perldoc perlvar)
    # local limits the change to the global $/ to this block
    local $/ = "";
    print <>;
}