使用perl正则表达式匹配文件中的多行字符串

时间:2014-03-19 21:30:19

标签: regex string perl multiline

我正在读取另一个perl文件并尝试查找文件中的引号包围的所有字符串,单行或多行。我已经很好地匹配了所有的单行,但是当我只想要字符串本身时,我无法在不打印整行的情况下匹配mulitlines。例如,下面是我正在阅读的内容片段:

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

# assign variable

my $string = 'Hello World!';
my $string4 = "chmod";
my $string3 = "This is a fun 
    multiple line string, please match";

所以我喜欢的输出是

'Hello World!';
"chmod";
"This is a fun multiple line string, please match";

但我得到了:

'Hello World!';
my $string4 = "chmod";
my $string3 = "This is a fun 
    multiple line string, please match";

这是我用来查找字符串的代码 - 所有文件内容都存储在@contents中:

my @strings_found = ();
my $line; 
for(@contents) {
    $line .= $_;
}

if($line =~ /(['"](.?)*["'])/s) {
    push @strings_found,$1;
}

print @strings_found;

我猜我只是得到了'Hello World!&#39 ;;正确的,因为我使用1美元,但我不知道如何在没有逐行循环的情况下找到其他人,我认为这会让很难找到多行字符串,因为它不知道下一行是什么是

我知道我的正则表达式是相当基本的并且没有考虑到一些注意事项,但我只想在进入更复杂的情况之前获得基本捕捉大多数正则表达式。

关于我哪里出错的指示?

2 个答案:

答案 0 :(得分:5)

结合大事,您需要使用正则表达式中的while修饰符在g循环中进行搜索。而且你还需要使用.*?关闭引号内的贪婪匹配。

use strict;
use warnings;

my $contents = do {local $/; <DATA>};

my @strings_found = ();

while ($contents =~ /(['"](.*?)["'])/sg) {
    push @strings_found, $1;
}

print "$_\n" for @strings_found;

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

# assign variable

my $string = 'Hello World!';
my $string4 = "chmod";
my $string3 = "This is a fun 
    multiple line string, please match";

输出

'Hello World!'
"chmod"
"This is a fun
    multiple line string, please match"

您不是第一个搜索此作业问题帮助的人。这是我给出的更详细的答案......好吧......你;)finding words surround by quotations perl

答案 1 :(得分:1)

默认情况下,regexp匹配(在perl和一般情况下)是贪婪的。所以你的正则表达式将匹配第一个&#39;或&#34;持续打印@strings_found数组的长度。我认为你的代码总是只有1个。

通过跟随*来改变它不贪心? /(&#39;&#34; * [&#34;&#39;])/ s的 我想。

它将以基本方式工作。如果你想要一个强大的解决方案,正则表达式是错误的方法。您可能希望为此编写解析代码。如果你在字符串中有不同的引号,那么贪婪会给你一个最大的字符串。如果开始或结束报价不同,非贪婪会给你最小的字符串而不关心。

了解贪婪和非贪婪。 另请注意/ m多行修改器。 http://perldoc.perl.org/perlre.html#Regular-Expressions