Regex Perl正则表达式问题
如何在Perl中匹配和存储$1、$2和$3变量中此字符串中的各行Regex Perl正则表达式问题,regex,perl,Regex,Perl,如何在Perl中匹配和存储$1、$2和$3变量中此字符串中的各行 $string = "This is a line 1.\nThis is line 2.\nThis is line 3.\n"; 我知道我必须使用/m修饰符,但到目前为止我的尝试都没有成功 我试过了 $string =~ m/^(.*?)$.^(.*?)$.^(.*?)$/sm; 和其他组合都没有用。我想保持简单,所以任何指出错误的答案都会有帮助。我只想尝试使用/s和/m修饰符。我修复了您的regexp: $string
$string = "This is a line 1.\nThis is line 2.\nThis is line 3.\n";
我知道我必须使用/m修饰符,但到目前为止我的尝试都没有成功
我试过了
$string =~ m/^(.*?)$.^(.*?)$.^(.*?)$/sm;
和其他组合都没有用。我想保持简单,所以任何指出错误的答案都会有帮助。我只想尝试使用/s和/m修饰符。我修复了您的regexp:
$string =~ m/^(.*?)\n(.*?)\n(.*?)$/sm;
“$”被视为变量(带有的警告使用警告;使用严格;
)
顺便说一句-将它们分配到阵列:
my @list = $string =~ m/^(.*?)\n(.*?)\n(.*?)$/sm;
为什么要使用
$
和^
来匹配中间换行符?这样做会更简单
$string =~ m/^(.*)\n(.*)\n(.*)/ ;
既没有/m也没有/s。或者干脆
($a,$b,$c) = split /\n/,$string ;
正在进行的是
$。
被解析为一个变量(它是其中一个特殊变量;输入文件中的行号):
一种解决方法是使用更多语法强制将$
解析为带有(?:$)
的正则表达式。但这很难看。我只想直接匹配新行(或使用拆分):
好的,我找到了<代码>$。被视为变量就是线索。我用过:
$string =~ m/^(.*?)$(.)^(.*?)$(.)^(.*?)$/sm;
并打印$1
,$3
,$5
谢谢大家。如果要使用变量
$1
、$2
和$3
,可以创建一个不将$视为变量的正则表达式字符串。
my ( $first_line, $second_line, $third_line, $rest_if_any )
= split( /\n/m, $string, 4 )
;
my $string = "This is a line 1.\nThis is line 2.\nThis is line 3.\n";
my $rex = q/^(.*?)$.^(.*?)$.^(.*?)$/; #The . between $ and ^ is the newline
$string =~ m/$rex/sm;
为了证明这是正确的,您可以使用Data::Dumper
use Data::Dumper;
print Dumper($1,$2,$3);
这将输出:
$VAR1 = 'This is a line 1.';
$VAR2 = 'This is line 2.';
$VAR3 = 'This is line 3.';
$VAR1 = 'This is a line 1.';
$VAR2 = '
';
$VAR3 = 'This is line 2.';
$VAR4 = '
';
$VAR5 = 'This is line 3.';
$VAR6 = '
';
更进一步,证明。在与换行符匹配的$和^之间,可以添加以下内容:
$rex = q/^(.*?)$(.)^(.*?)$(.)^(.*?)$(.)/;
$string =~ m/$rex/sm;
print Dumper($1,$2,$3,$4,$5,$6);
这将输出:
$VAR1 = 'This is a line 1.';
$VAR2 = 'This is line 2.';
$VAR3 = 'This is line 3.';
$VAR1 = 'This is a line 1.';
$VAR2 = '
';
$VAR3 = 'This is line 2.';
$VAR4 = '
';
$VAR5 = 'This is line 3.';
$VAR6 = '
';
%list
不是一个列表,而是一个散列。我不确定混合/sm
会对这个正则表达式产生什么影响。假设,它将匹配<代码> \\\\\n\\nb\n\n\nne“< /代码>,不是吗?嗯,我认为<代码> ^ $ 使用<代码> /M< /代码>修饰符将在字符串的中间匹配<代码> \n>代码>。请尝试在以下位置打印列表:@list=“\n\n\nA\nB\n\nC\nD\nE”=~/^(.*?)\n(.*?)\n(.*?$)(.*)/sm
其次,如果您的量词贪婪,则在正则表达式中,/s
修饰符将匹配\n
。在这种情况下,实际上不需要/sm
。@sln是正确的/m使“^”和“$”匹配每个嵌入的换行符。从文档:一起使用,如/ms,它们允许“.”匹配任何字符,同时仍然允许“^”和“$”分别匹配字符串中换行符之后和之前的换行符。
如果只有3行为正,为什么需要^和\n?$
?如果不是肯定的,则\n?$
部分将与此处的某些单词\n\n不匹配。答案已更正,以匹配前3行,而忽略其余部分,因此它与拆分解决方案的功能相匹配(或多或少)。我希望在解决此问题时看到/m/s起作用。@abc:您为什么坚持使用/m
和/s
?他们只是碍事,这不是解决办法。首先,您不应该试图使用$
来匹配换行符。这是一个零宽度断言;它与换行前的空字符串匹配。@abc:有人已经说过了。是的,不管怎样,“\n”=~/$(?:)/sm代码>或“\n”=~/(?:$)/sm
,则“”。
将仅匹配换行符(以非捕获方式)。但是,正如@Alan More所说,这并不是一个真正的解决方案,而是一种观察。你可能希望在整个过程中将(.)改为(?:),以避免捕获你不关心的群体。仍然建议使用之前发布的惯用代码,而不是这种特殊的困扰。