Perl提取文本



我已经做了这么长时间了!我很感激你的帮助。。。

我的医生会是什么样子:

<text>
<text> command <+>= "stuff_i_need" <text>
<text>
<text> command <+>= stuff <text>
<text>
<text> command <+>= -stuff <text>
<text>
  • 任何周围有缠结括号的东西都是可选的
  • 东西可以是任何东西(苹果、桔子、香蕉),但这正是我需要提取的
  • 命令已修复

到目前为止我的代码:

#!/usr/bin/env perl
use warnings;
use strict;
use Text::Diff;
# File Handlers 
open(my $ofh, '>in.txt');
open(my $ifh, '<out.txt');
while (<$ifh>)
{
    # Read in a line
    my $line = $_;
    chomp $line;
    # Extract stuff
    my $extraction = $line;
    if ($line =~ /command += /i) {        
        $extraction =~ s/.*"(.*)".*/$1/;
        # Write to file
        print $ofh "$extractionn";
    }
}

基于示例输入:

 if ($line =~ /commandd*s*+?=s*["-]?(w+)"?/i) {    
    $extraction = $1; 
    print "$extractionn";
 }   

几件事:

  1. 对于提取,不要使用替换(即,使用m//而不是s///)。如果使用匹配,则匹配中的括号组将作为列表返回(如果愿意,则分配给$1$2$3等)
  2. =~绑定要匹配的变量。所以你希望$extraction实际上是$line
  3. 你的.*匹配过于贪婪,会阻止匹配以你想要的方式成功。我所说的"贪婪"是指.*将与您行中的尾随"匹配。它将消耗行上的其余输入,然后尝试匹配",但由于到达了行的末尾而失败

你想指定单词的含义。例如,如果它是字母,那么匹配[a-zA-Z]

my ($extraction) = $line =~ /command += "([a-zA-Z]*)"/;

如果是数字,则需要[0-9]:

my ($extraction) = $line =~ /command += "([0-9]*)"/;

如果它可以是除"之外的任何内容,请使用[^"],意思是"除"之外的任何东西":

my ($extraction) = $line =~ /command += "([^"]*)"/;

这通常有助于尝试匹配你想要的东西,而不是毯子.*

以下正则表达式将对您有所帮助:

m{
    (?<= = )        # Find an `=`
    s*             # Match 0 or more whitespaces
    (?:             # Do not capture
        [ " - ]    # Match either a `"` or a `-`
    )?              # Match once or never
    (               # Capture
        [^ " s ]+  # Match anything but a `"` or a whitespace
    )
}x;

下面的一行将提取一个单词(一个没有空格的字符序列),该单词后跟一个等号,前缀是可选的加号,周围是可选的引号。它将从in.txt读取并写入out.txt

perl -lne 'push @a, $1 if /commands*+?=s*("?S+"?)/ }{ 
    print for @a' in.txt > out.txt

完整的代码-如果你喜欢脚本形式-是:

BEGIN { $/ = "n"; $ = "n"; }
LINE: while (defined($_ = <ARGV>)) {
    chomp $_;
    push @a, $1 if /commands*+?=s*("?S+"?)/;
}
{
    print $_ foreach (@a);
}

由O模块的Deparse功能提供。

一种轻型解决方案。

#!/usr/bin/env perl
use warnings;
use strict;
open my $ifh, '<','in.txt';
open my $ofh, '>', 'out.txt';
while (<$ifh>)
{
    if (/
        s commands+?=s
        (?:-|("))?     # The word can be preceded by an optional - or "
        (w+)
        (?(1)1)s+    # If the word is preceded by a " it must be end 
                       # with a "
        /x)
    {
        print $ofh $2."n";
    }
}

最新更新