2012-08-17 104 views
3

我一直在研究這麼久! 我會感激你的幫助......Perl提取文本

我的文檔將是什麼樣子:

<text> 
<text> command <+>= "stuff_i_need" <text> 
<text> 
<text> command <+>= stuff <text> 
<text> 
<text> command <+>= -stuff <text> 
<text> 
  • 任何與糾結括號是可選
  • 東西可以是任何東西(蘋果,橘子,香蕉),但它是什麼,我需要提取
  • 命令固定

我碼S ø遠:

#!/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"; 
    } 
} 
+1

您需要指定哪些運算符是有效的。在你的代碼中你只能看到'+ =',但是在你的示例輸入中你有'+ ='和'='。 'command' vs'command2'也是一樣。當你想提取單詞時,你需要指定確切的條件。 – TLP 2012-08-17 18:28:21

+0

感謝提示@TLP。我做了一些更改,請讓我知道是否有幫助。 – Ryan 2012-08-17 18:40:17

回答

2

基於示例性輸入:

if ($line =~ /command\d*\s*\+?=\s*["-]?(\w+)"?/i) {  
    $extraction = $1; 
    print "$extraction\n"; 
} 
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 \+= "([^"]*)"/; 

通常有助於試圖匹配只是你在找什麼FO而不是毯子.*

+0

根據樣本輸入,在匹配的單詞周圍不需要引號。 – newfurniturey 2012-08-17 18:38:14

+0

不,他們不是,但我一次只想修理一件事。如果他能得到一場比賽,他可以開始調整,並從那裏開始工作。在這個問題中有太多問題需要在這裏的任何一個答案中處理。 – zostay 2012-08-17 18:39:29

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; 
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); 
} 

the O module的Deparse功能的禮貌。

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"; 
    } 
}