使用正则表达式替换子串

时间:2013-05-02 13:48:36

标签: regex perl

我在学习Perl正则表达式的过程非常糟糕。我想:

  • 使用以下内容替换行尾的所有单个######
  • 将所有出现的#个字符(忽略前导或尾随空格)替换为
    # ---------- #

我知道它s/#,但这就是我所知道的,我能找到的一切。任何建议。

2 个答案:

答案 0 :(得分:4)

一行的开头由^匹配。因此,以#开头的行与

匹配
/^#/

如果您希望#为单身,即未跟随另一个#,则必须添加否定字符类:

/^#[^#]/

我们不想替换#之后的字符,因此我们会将其替换为非匹配组(称为否定预见):

/^#(?!#)/

要添加替换,只需将其更改为

即可
s/^#(?!#)/#####/

整行可以通过以下正则表达式进行匹配:

/^#+$/

Plus表示“一次或多次”,^$已经解释过了。我们只需要忽略前导和尾随空格(*表示“零或更多”):

/^ *#+ *$/

我们不希望替换空格,所以我们必须保留它们。括号创建“捕获组”,编号从1开始:

s/^( *)#+( *)$/$1# ---------- #$2/

答案 1 :(得分:2)

首次更换:

$line =~ s/^#/#####/;

这里的想法是你希望任何启动的行带有'#'。正则表达式中的'^'表示后面的内容必须位于字符串的开头。

第二次替换:

$line =~ s/^#+$/# ---------- #/;

再次使用'^'和'$'。最后的'$'表示之前的内容必须到达字符串的末尾。 '#+'表示必须有一个或多个'#'字符。因此,换句话说,整个字符串必须包含'#'。

这是一个测试脚本并运行:

$ cat foo.pl
#! /usr/bin/perl

use strict;
use warnings;

my @lines = (
        "foo line",
        "# single comment",
        "another line",
        "#############",
        "# line",
        "############",
);

foreach my $line( @lines ){
        print "ORIGINAL:  $line\n";
        $line =~ s/^#/#####/;
        $line =~ s/^#+$/# ---------- #/;
        print "NEW:       $line\n";
        print "\n";
}

$ ./foo.pl
ORIGINAL:  foo line
NEW:       foo line

ORIGINAL:  # single comment
NEW:       ##### single comment

ORIGINAL:  another line
NEW:       another line

ORIGINAL:  #############
NEW:       # ---------- #

ORIGINAL:  # line
NEW:       ##### line

ORIGINAL:  ############
NEW:       # ---------- #