【问题标题】:perl : String extraction based on pattern match [closed]perl:基于模式匹配的字符串提取 [关闭]
【发布时间】:2012-08-13 13:21:52
【问题描述】:

一个文件 FILE1 有几千行带有终止模式 _Pattern1。

第二个文件也有数千行具有相同的终止模式_Pattern1。

我现在必须:

  • 逐行读取FILE1

  • 查看该行是否有任何以 _Pattern1 结尾的字符串

  • 提取字符串并将其存储到变量中

  • 打开FILE2并逐行读取

  • 找出刚刚从 FILE2 读取的行是否包含存储在上述变量中​​的字符串

在 perl 中如何做到这一点?

EDIT2:

好的,通过谷歌搜索并参考下面列出的链接,我解决了我的问题。 这是代码sn-p。

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

my $OriginalHeader=$ARGV[0]; ## Source file
my $GeneratedHeader=$ARGV[1];## File to compare against
my $DeltaHeader=$ARGV[2];    ## File to store misses

my $MatchingPattern="_Pos";
my $FoundPattern;

open FILE1, $OriginalHeader or die $!;
open FILE2, $GeneratedHeader or die $!;
open (FILE3, ">$DeltaHeader") or die $!;

my $lineFromOriginalHeader;
my $lineFromGeneratedHeader;
my $TotalMacrosExamined = 0;
my $TotalMacrosMissed = 0;

while($lineFromOriginalHeader=<FILE1>)
{
 if($lineFromOriginalHeader =~ /$MatchingPattern/)
  {
    my $index = index($lineFromOriginalHeader,$MatchingPattern);

    my $BackIndex = $index;
    my $BackIndexStart = $index;

    $BackIndex = $BackIndex - 1;

    ## Use this while loop to extract the substring. 
    while (1)
    {
      my $ExtractedChar = substr($lineFromOriginalHeader,$BackIndex,1);
      if ($ExtractedChar =~ / /)
      {
        $FoundPattern = substr($lineFromOriginalHeader,$BackIndex + 1,$BackIndexStart + 3 - 
                                                                                $BackIndex); 
        print "Identified $FoundPattern \n";
        $TotalMacrosExamined = $TotalMacrosExamined + 1;
        ##Skip the next line
        $lineFromOriginalHeader = <FILE1>;
        last;       
      }
     else
     {
      $BackIndex = $BackIndex - 1;
     }

   } ##while(1)

 ## We now look for $FoundPattern in FILE2
 while ($lineFromGeneratedHeader = <FILE2>)
 {
  if (index($lineFromGeneratedHeader,$FoundPattern)!= -1)
   {
     ##Pattern found. Reset file pointer and break out of while loop
     seek FILE2,0,0;
     last;
   }
   else
   {
     if (eof(FILE2) == 1)
      {         
        print FILE3 "Generated header misses $FoundPattern\n";
        $TotalMacrosMissed = $TotalMacrosMissed + 1;
        seek FILE2,0,0; 
        last;       
      }
   }
} ##while(1)

}
else
{
  ##NOP
}
} ##while (linefromoriginalheader)

close FILE1;
close FILE2;
close FILE3;
print "Total number of bitfields examined = $TotalMacrosExamined\n";
print "Number of macros obsolete = $TotalMacrosMissed\n";

【问题讨论】:

  • 您很好地概述了这些步骤。你是 Perl 的新手,还是不管是哪种语言的编程新手?如果您是 Perl 新手,您所描述的几乎所有内容都可以在 perldoc.perl.org/perlintro.html 中找到
  • 有不止一种方法可以做到这一点,这里有一个:$ perl -ne'exec q;perl;, "-ne", q $print (/\Q$.$1.q;/?"$. YES":$. .q\; NO\;);, "file2" if m;^(.*)_pat1;' file1 这应该可以解决问题,减去一些陷阱。我不知道这是否可以编译,但我喜欢它的外观。请注意使用exec 作为循环终止符。而且我什至没有必须分配给单个变量 :-) 当然还有更简单的方法 — What have you tried?
  • 当使用正则表达式时,我们可以声明捕获组,用括号括起我们想要捕获的所有内容。然后,您的正则表达式将类似于 /($MatchingPattern)/。该组的内容将在特殊变量$1 中,直到您进行另一个正则表达式匹配。 Perl's regexp tutorial 在学习 perl 正则表达式时可能会派上用场。
  • 我对编程并不陌生。只是我以前几乎没有使用过perl。 Perl 肯定很有趣!
  • It's OK to Ask and Answer Your Own Questions,但请以问答方式分享您的知识,将您的答案作为实际答案发布,但不在在您的问题中。这允许对答案进行投票/接受,并帮助我们保持“未回答”列表更加清晰。谢谢。

标签: string perl pattern-matching


【解决方案1】:

只是让您的代码更加 Perly 的第一步。实际上还有很多事情要做,包括在 Perl 中通常使用 $some_var$SomeVar,但我没有做到这一点。

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

my ($OriginalHeader, $GeneratedHeader, $DeltaHeader) = @ARGV;
my $MatchingPattern=qr/(\S*_Pos)/; # all non-whitespace terminated by _Pos

open my $file1, '<', $OriginalHeader  or die $!;
open my $file2, '<', $GeneratedHeader or die $!;
open my $file3, '>', $DeltaHeader     or die $!;

my $TotalMacrosExamined = 0;
my $TotalMacrosMissed = 0;

while(my $lineFromOriginalHeader=<$file1>) {
  next unless $lineFromOriginalHeader =~ $MatchingPattern;
  my $FoundPattern = $1; # matched string

  print "Identified $FoundPattern \n";
  $TotalMacrosExamined++;

  ##Skip the next line
  <$file1>;

  ## We now look for $FoundPattern in FILE2
  my $match_found = 0;
  while (my $lineFromGeneratedHeader = <$file2>) {
    if (index($lineFromGeneratedHeader,$FoundPattern)!= -1) {
      ##Pattern found. Close the file and break out of while loop
      $match_found++;
      last;
    } 
  }

  unless ($match_found) {
    print $file3 "Generated header misses $FoundPattern\n";
    $TotalMacrosMissed++;
  }

  seek $file2,0,0;

}

print "Total number of bitfields examined = $TotalMacrosExamined\n";
print "Number of macros obsolete = $TotalMacrosMissed\n";

【讨论】:

    【解决方案2】:

    我一生都在用 C 编程,我用谷歌搜索了下面 perl 结构的用法,并编写了一个类似 C 的程序。这对我来说完美无缺。 :-)

    编辑:这是为了澄清为什么我必须在下面的算法中跳过一行。在第二个文件中检索并随后搜索的模式出现在两个连续的行上。因此,可靠地检测到它的第一次出现就足够了。也是一个挑剔,始终保证包含模式的子字符串始终是该行的第二个子字符串。

    例如#define Something_Pos(一些值)

    #!/usr/bin/perl
    use strict;
    use warnings;
    
    my $OriginalHeader=$ARGV[0];
    my $GeneratedHeader=$ARGV[1];
    my $DeltaHeader=$ARGV[2];
    
    my $MatchingPattern="_Pos";
    my $FoundPattern;
    
    open FILE1, $OriginalHeader or die $!;
    open FILE2, $GeneratedHeader or die $!;
    open (FILE3, ">$DeltaHeader") or die $!;
    
    my $lineFromOriginalHeader;
    my $lineFromGeneratedHeader;
    my $TotalMacrosExamined = 0;
    my $TotalMacrosMissed = 0;
    
    while($lineFromOriginalHeader=<FILE1>)
    {
     if($lineFromOriginalHeader =~ /$MatchingPattern/)
     {
      my $index = index($lineFromOriginalHeader,$MatchingPattern);
    
      my $BackIndex = $index;
      my $BackIndexStart = $index;
    
      $BackIndex = $BackIndex - 1;
    
      ## Use this while loop to extract the substring. 
      while (1)
      {
       my $ExtractedChar = substr($lineFromOriginalHeader,$BackIndex,1);
       if ($ExtractedChar =~ / /)
        {
         $FoundPattern = substr($lineFromOriginalHeader,$BackIndex + 1,$BackIndexStart + 3 - 
                                                                                    $BackIndex); 
         print "Identified $FoundPattern \n";
         $TotalMacrosExamined = $TotalMacrosExamined + 1;
         ##Skip the next line
         $lineFromOriginalHeader = <FILE1>;
         last;       
        }
       else
        {
         $BackIndex = $BackIndex - 1;
        }
    
    } ##while(1)
    
     ## We now look for $FoundPattern in FILE2
    while ($lineFromGeneratedHeader = <FILE2>)
    {
     ##print "Read the following line from FILE2: $lineFromGeneratedHeader\n";
    
      if (index($lineFromGeneratedHeader,$FoundPattern)!= -1)
       {
         ##Pattern found. Close the file and break out of while loop
         seek FILE2,0,0;
         last;
       }
       else
       {
         if (eof(FILE2) == 1)
          {         
            print FILE3 "Generated header misses $FoundPattern\n";
            $TotalMacrosMissed = $TotalMacrosMissed + 1;
            seek FILE2,0,0; 
            last;       
          }
       }
     } ##while(1)
    
    }
    else
    {
    
    }
    } ##while (linefromoriginalheader)
    
    close FILE1;
    close FILE2;
    close FILE3;
    print "Total number of bitfields examined = $TotalMacrosExamined\n";
    print "Number of macros obsolete = $TotalMacrosMissed\n";
    

    【讨论】:

    猜你喜欢
    • 2013-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-16
    • 1970-01-01
    • 2013-06-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多