正则表达式(perl)将匹配(全局)一行或多行以外的行,而不是行的开头

时间:2012-11-28 22:54:42

标签: regex perl

我的理解是/[^\A] +/mg将全局匹配一个或多个空格,而不是在字符串的开头或刚刚在换行符之后。

显然,我错了。

#!/usr/bin/env perl
use strict;
use warnings;

my $str = "         word1     word2\n     word3     word4     word5\n";
print "str before = $str\n";
$str =~ s/[^\A] +/ /mg;
print "str after  = $str\n";

输出:

str before =          word1     word2
     word3     word4     word5

str after  =  word word2 word word word5

所需的输出是:

str before =          word1     word2
     word3     word4     word5

str after  =          word1 word2
     word3 word4 word5

因此前导空格的数量保留不变,但每行开头后出现的多个空格缩小为一个空格。

我找不到我在perldoc perlretutperldoc perlre中寻找的内容(甚至在搜索了所有“{^”与/\[\^的实例后)。非常感谢,提前。

3 个答案:

答案 0 :(得分:5)

在Perl中,最简单的解决方案是:s/\S\K +/ /g;

请参阅 this demo

答案 1 :(得分:3)

我认为你不能在字符类中使用\A,因为它不是一个字符。你可以选择两个负面的前瞻:

$str =~ s/(?<!^)(?<! ) +/ /mg;

确保匹配既不能在行开头之后也不能在另一个空格之后开始。后一个条件很重要,否则如果你在行的开头有多个空格,那么正则表达式只会从第二个开始匹配。

顺便说一句,为了提高在正则表达式中使用文字空格字符的可读性,一个巧妙的技巧是将它们包装在一个字符类中:

$str =~ s/(?<!^)(?<![ ])[ ]+/ /mg;

Working demo.

答案 2 :(得分:0)

正如m.buettner所说,像[...]这样的正则表达式是字符类并且只包含字符,而不是模式。实际上,您的代码会生成警告

Unrecognized escape \A in character class

但是一行不在行开头的空格是一串以非空格开头的空格,所以你需要写的就是这个。

use strict;
use warnings;

my $str = "         word1     word2\n     word3     word4     word5\n";

print qq(String before = "$str"\n);

$str =~ s/[^ ]\K +/ /g;

print qq(String after = "$str"\n);

<强>输出

String before = "         word1     word2
     word3     word4     word5
"
String after = "  word1 word2
 word3 word4 word5
"