1

我在学习 Perl 正则表达式方面过得很糟糕。我在尝试着 :

  • #将所有出现在行首的单个替换为: #####
  • 将所有出现的整行#字符(忽略前导或尾随空格)替换为
    # ---------- #.

我知道它s/#,但这就是我所知道的和我能找到的全部。有什么建议么。

4

2 回答 2

4

行首由 匹配^。因此,以 a 开头的行#匹配

/^#/

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

/^#[^#]/

我们不想替换 后面的字符#,所以我们将用一个不匹配的组替换它(称为负前瞻):

/^#(?!#)/

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

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

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

/^#+$/

加的意思是“一次或多次”,^已经$解释过了。我们只需要忽略前导和尾随空格(*意思是“零个或多个”):

/^ *#+ *$/

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

s/^( *)#+( *)$/$1# ---------- #$2/
于 2013-05-02T14:01:16.853 回答
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:       # ---------- #
于 2013-05-02T14:02:40.923 回答