我在学习 Perl 正则表达式方面过得很糟糕。我在尝试着 :
#
将所有出现在行首的单个替换为:#####
。- 将所有出现的整行
#
字符(忽略前导或尾随空格)替换为
# ---------- #
.
我知道它s/#
,但这就是我所知道的和我能找到的全部。有什么建议么。
行首由 匹配^
。因此,以 a 开头的行#
匹配
/^#/
如果您希望#
是单一的,即不跟随另一个#
,则必须添加一个否定字符类:
/^#[^#]/
我们不想替换 后面的字符#
,所以我们将用一个不匹配的组替换它(称为负前瞻):
/^#(?!#)/
要添加替换,只需将其更改为
s/^#(?!#)/#####/
整行可以通过以下正则表达式匹配:
/^#+$/
加的意思是“一次或多次”,^
已经$
解释过了。我们只需要忽略前导和尾随空格(*
意思是“零个或多个”):
/^ *#+ *$/
我们不希望这些空间被替换,所以我们必须保留它们。括号创建从 1 开始编号的“捕获组”:
s/^( *)#+( *)$/$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: # ---------- #