【问题标题】:Matching multiline string in file using perl regex使用 perl 正则表达式匹配文件中的多行字符串
【发布时间】:2014-03-19 21:30:18
【问题描述】:

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

#!/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!”;正确,因为我使用的是 $1 但我不确定如何在不逐行循环的情况下找到其他人,我认为这会很难找到多行字符串,因为它不知道下一行是什么。

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

关于我哪里出错的任何指针?

【问题讨论】:

  • 我也尝试用空格替换 '\n' 但没有奏效。

标签: regex string perl multiline


【解决方案1】:

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

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

【讨论】:

  • 感谢您的帮助伙伴!解决方案效果很好,但突出显示了我的正则表达式中的问题......但又一次!
  • 是的,正如我在上一个问题中所说,这是一个比表面上看起来要困难得多的问题。祝您继续探索顺利
  • 感谢您对这两个方面的帮助,它帮助我解决了一些问题!
【解决方案2】:

regexp 匹配(在 perl 和一般情况下)默认情况下是贪婪的。因此,您的正则表达式将从第一个 ' 或 " 匹配到最后一个。打印您的 @strings_found 数组的长度。我认为您拥有的代码将始终为 1。

在 * 后面加上 ? /('"*?["'])/s 我想。

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

了解贪婪和非贪婪。 还要注意 /m 多行修饰符。 http://perldoc.perl.org/perlre.html#Regular-Expressions

【讨论】:

  • 感谢您的意见。你有你谈论的解析代码的例子吗?不必是我的问题的确切解决方案,只需一个我可以用来开发自己的答案的解决方案。
  • 没有方便的例子。我会考虑在 c:-/ 中用 strtok 做一些复杂的事情。使用正则表达式确保您尝试不贪婪。这将使简单的基本解决方案起作用。如果您需要处理字符串中的引号,那么在正则表达式中分离引号也可能会给您带来更好的结果? . . .也许 /(("[^"]*?")|('[^']*?'))*?/s 对不起,我现在不打算玩这个了。
  • 别担心,我只是想问问,谷歌是我的朋友!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-12
  • 2021-10-29
  • 2014-03-06
  • 2014-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多