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

一些东西:

  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 \+= "([^"]*)"/;

尝试匹配您正在寻找的东西而不是毯子通常会有所帮助.*

于 2012-08-17T18:34:45.423 回答
2

基于示例输入:

 if ($line =~ /command\d*\s*\+?=\s*["-]?(\w+)"?/i) {    
    $extraction = $1; 
    print "$extraction\n";
 }   
于 2012-08-17T18:31:09.893 回答
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

下面的单行将提取一个单词(一个不带空格的字符序列),该单词后面有一个等号,前面有一个可选的加号,并用可选的引号括起来。它将读取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 回答
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 回答