4

私はこれに長い間取り組んできました!助けていただければ幸いです...

私のドキュメントは次のようになります。

<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 "$extraction\n";
    }
}
4

5 に答える 5

2

入力例に基づいて:

 if ($line =~ /command\d*\s*\+?=\s*["-]?(\w+)"?/i) {    
    $extraction = $1; 
    print "$extraction\n";
 }   
于 2012-08-17T18:31:09.893 に答える
2

いくつかのこと:

  1. 抽出には、置換を使用しないでください (つまり、 use m//and not 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 \+= "([^"]*)"/;

通常、ブランケットではなく、探しているものと一致させようとするのに役立ちます.*

于 2012-08-17T18:34:45.423 に答える
1

次の正規表現が役立ちます。

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;
于 2012-08-17T18:35:54.283 に答える
0

軽い解決策。

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

open my $ifh, '<','in.txt';
open my $ofh, '>', 'out.txt';

while (<$ifh>)
{
    if (/
        \s command\s\+?=\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";
    }
}
于 2012-08-17T21:47:30.940 に答える
0

次のワンライナーは、オプションのプラス記号を前に付け、オプションの引用符で囲んだ等号に続く単語 (スペースを含まない一連の文字) を抽出します。からin.txt読み書きしout.txtます。

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

完全なコード (スクリプト形式を好む場合) は次のとおりです。

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

O モジュールの Deparse 関数のおかげです。

于 2012-08-17T18:36:32.443 に答える