【问题标题】:Need to match a multiline string using perl [closed]需要使用 perl 匹配多行字符串 [关闭]
【发布时间】:2014-11-02 07:27:45
【问题描述】:

我知道这个问题已经在这个论坛上被问过好几次了,我检查了大多数的答案,但仍然无法让它适用于我的输入文件:

输入文件:

flow items
{
Flow Item1
{
    Result -2
    {
        line1;
        line2;
        line3;
    }       

    Result 0
    {
        line4;
        START_TEXT blah blah blah;
        blah blah blah_END_TEXT;
        line4;
    }       
    Result 1
    {
        line5;
        START_TEXT foo foo foo;
        line5;
    }       
    Result 2
    {
        line6;
        START_TEXT blah1 blah1 blah1;
        blah1 blah1 blah1_END_TEXT;
        line7;
    }       
}   

Flow item2
{
    Result -2
    {
        line8;
        line9;
        line10;
    }       

    Result 0
    {
        line11;
        START_TEXT blah2 blah2 blah2;
        blah2 blah2 blah2_END_TEXT;
        line12;
    }       
    Result 1
    {
        line13;
        START_TEXT foo1 foo1 foo1;
        line14;
    }       
}
}

预期输出:

START_TEXT blah blah blah;
blah blah blah_END_TEXT;
START_TEXT blah1 blah1 blah1;
blah1 blah1 blah1_END_TEXT;
START_TEXT blah2 blah2 blah2;
blah2 blah2 blah2_END_TEXT;

所以基本上有多次出现的 START_TEXT 是不需要的(那些在同一个结果块中没有 END_TEXT 的,例如:

    Result 1
    {
        line5;
        START_TEXT foo foo foo;
        line5;
    }       

我一直在尝试的代码(查看工作目录中的所有 .txt 文件并搜索多行模式:

#!/usr/bin/perl
use strict;
use warnings;
use Cwd;
use File::Find;

my $file_pattern  ="txt";

find(\&d, cwd);

sub d {

  my $file = $File::Find::name;

  $file =~ s,/,\\,g;

  return unless -f $file;
  return unless $file =~ /$file_pattern/;

  open F, $file or print "couldn't open $file\n" && return;
  open $fout, ">>", "Result.txt";
  while (<F>) {

    $string =~ /(START_TEXT.*?)END_TEXT/s;
    print $fout "$string\n";;

  }

  close F;
  close $fout;
}

这只会返回几个换行符。请帮忙。

【问题讨论】:

  • 这篇文章一团糟,令人遗憾。您的数据没有平衡括号; line4line13 没有尾随分号,而所有其他人都有;您的示例代码尝试处理当前目录或名称中包含 txt 的任何子目录中的所有文件;您使用诸如d 之类的荒谬标识符作为您的回调,并使用F$fout 作为您的文件句柄。然而,您却在向我们寻求解决方案!您的第一步应该是清理您的行为,并返回对状态和问题的正确描述。
  • 对不起,下次会小心的。
  • 我已经更正了输入文件。而且我的编程很糟糕,因为我的工作档案专注于硬件,只需要在这里和那里编写一两个脚本来获取数据。这并不能证明不提高我的编程技能是正当的,而只是说明我的情况。我正在努力提高脚本编写能力:)

标签: regex perl


【解决方案1】:

您可以将Input Record Separator 设置为}

use strict;
use warnings;
use autodie;

open my $fh, '<', 'input.file';

local $/ = "}";

while(<$fh>) {
    next unless my ( $cap ) = /(START_TEXT.*END_TEXT;)/s;
    $cap =~ s/\n\s*/\n/g;
    print $cap, "\n";
}

输出:

START_TEXT blah blah blah;
blah blah blah_END_TEXT;
START_TEXT blah1 blah1 blah1;
blah1 blah1 blah1_END_TEXT;
START_TEXT blah2 blah2 blah2;
blah2 blah2 blah2_END_TEXT;

【讨论】:

  • 又短又甜,我喜欢。
  • 感谢 Jaypal,它工作并提供了所需的输出 :)
  • @kaur 很高兴它对你有用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-30
  • 1970-01-01
  • 2018-08-03
  • 2018-06-15
  • 2012-08-13
  • 1970-01-01
相关资源
最近更新 更多