2014-11-03 28 views
-4

我正在尋找的txt文件,找到包含一些字符的文本,而在另一個文件夾移動他們...PERL - 搜索文本字符串,得到的結果與子以及

我正在尋找的以下兩個關鍵字:

95-B/A 
95-ASB/A 

我的代碼看起來像

月1日編輯:把整個代碼

use warnings; 
use File::Copy; 
use File::Basename; 
my (%count,%countNegative,%countPositive,$i,$j,$key,@keys,@keysNegative,@keysPositive,$token,$tokenNegative,$tokenPositive,@tokens,@tokensNegative,@tokensPositive,$totalCount,$negativeCount,$positiveCount,$totalCountNegativeInText,$totalCountPositiveInText); 



@files = <*.txt>; 
foreach $fileToProcess (@files) { 
open(INFILE,"<$fileToProcess") or die("cannot open file"); 
while (<INFILE>) { 
@tokens = &tokenize($_); 
    foreach $token (@tokens) { 
     if ($token =~ /[a-zA-Z]/) { 
     $count{$token} = $count{$token} ? $count{$token}+1 : 1; 
     } 
    } 
} 

@keys = keys %count; 
@keys = sort { $count{$b} <=> $count{$a} } @keys; 

for ($i=0;$i<=$#keys;$i++) { 
    if ((lc $keys[$i] eq lc '95-B/A') || (lc $keys[$i] eq lc '95-ASB/A')) { 
    $oldlocation = $fileToProcess; 
    $newlocation = '95BA'; 
    File::Copy::move($oldlocation, $newlocation); 
    } 
} 

close(INFILE); 
} 
exit(0); 


use strict; 

my $true = 1; 
my $false = 0; 
my $text = ""; 
my $word; 
# read text 
while (<>) { $text .= $_; } 
foreach $word (&tokenize($text)) { 
    &printText(&rule3(&rule2(&rule1(&makeUnits(&cleanUp($word)))))); 
} 
print "\n"; 
exit(0); 

sub tokenize { 
    $_ = $_[0]; 
    s/\s+/\n/g; 
    s/^\n//; 
    s/$/\n/; 
    s/([.,!?:;,])\n/\n$1\n/g; 
    s/\n(["'`])([^\n])/\n$1\n$2/g; 
    s/([^\n])(["'`])\n/$1\n$2\n/g; 
    s/([^\n])([.,])\n/$1\n$2\n/g; 
    s/\n([A-Z])\n\./\n$1./g; 
    s/\n\.\n([^"A-Z])/\.\n$1/g; 
    s/(\.[A-Z]+)\n\.\n/$1.\n/g; 
    s/([^\n])'s\n/$1\n's\n/g; 
    s/([^\n])n't\n/$1\nn't\n/g; 
    s/([^\n])'re\n/$1\n're\n/g; 
    s/\n\$([^\n])/\n\$\n$1/g; 
    s/([^\n])%\n/$1\n%\n/g; 
    s/Mr\n\.\n/Mr.\n/g; 
    return(split(/\n/,$_)); 
} 

sub printText { 
    my $i; 
    for ($i=0;$i<@_;$i++) { 
     print join('',reverse(split(//,&breakUnits($_[$i])))); 
    } 
    print " "; 
} 

它選擇那些有95-B/A 95-ASB/A的人,但它也選擇那些有95-B和95-ASB的人(我不想那樣,我只想挑選那些有95-B/A和95-ASB/A)。

我想我在處理正斜槓時出錯了嗎?有沒有人有辦法解決嗎?

在此先感謝

第二編輯:我想如果我把循環在那裏我找到令牌裏面的字符串檢查,它工作得很好。顯然我被搞亂鑰匙放在了哈希,當我在做請檢查下一步,但我沒有看到我不應該在第一步使用令牌的原因。您是怎麼想的?

@files = <*.txt>; 
foreach $fileToProcess (@files) { 
open(INFILE,"<$fileToProcess") or die("cannot open file"); 
while (<INFILE>) { 
@tokens = &tokenize($_); 
    foreach $token (@tokens) { 
     if ($token =~ /[a-zA-Z]/) { 
     if (($token eq '95-B/A') || ($token eq '95-ASB/A')) 
     { 
       $oldlocation = $fileToProcess; 
    $newlocation = '95BA'; 
    File::Copy::move($oldlocation, $newlocation); 
     } 
     $count{$token} = $count{$token} ? $count{$token}+1 : 1; 
     } 
    } 
} 
+0

https://eval.in/216716 – 2014-11-03 16:26:33

+0

Perl。這是Perl。 – Borodin 2014-11-03 16:51:37

+1

您需要向您展示*真實*代碼。我確定這不是它,因爲'$ oldlocation'和'$ newlocation'在循環內部不會改變,並且獨立於散列鍵。如果這是真的,那麼每次碰巧在任意哈希中找到匹配時,都會移動相同的文件。 – Borodin 2014-11-03 16:59:40

回答

1

我刪除了代碼中不需要的部分,並將其修改爲更易讀。現在很清楚問題是什麼:%count幾乎是全球性的,但每個文件需要新的%count

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

my @files = glob '*.txt'; 

for my $fileToProcess (@files) { 
    my %count; # <---- HERE. Declare %count in the loop. 
    open my $IN, '<', $fileToProcess or die "Cannot open $fileToProcess: $!"; 
    while (<$IN>) { 
     for my $token (tokenize($_)) { 
      if ($token =~ /[a-zA-Z]/) { 
       ++$count{$token};  # Ternary ? : not needed. 
      } 
     } 
    } 

    my @keys = sort { $count{$b} <=> $count{$a} } keys %count; 

    for my $key (@keys) { 
     if (lc $key eq lc '95-B/A' or lc $key eq lc '95-ASB/A') { 
      print "move $fileToProcess because of $key.\n" 
     } 
    } 
} 

sub tokenize { 
    $_ = $_[0]; 
    s/\s+/\n/g; 
    s/^\n//; 
    s/$/\n/; 
    s/([.,!?:;,])\n/\n$1\n/g; 
    s/\n(["'`])([^\n])/\n$1\n$2/g; 
    s/([^\n])(["'`])\n/$1\n$2\n/g; 
    s/([^\n])([.,])\n/$1\n$2\n/g; 
    s/\n([A-Z])\n\./\n$1./g; 
    s/\n\.\n([^"A-Z])/\.\n$1/g; 
    s/(\.[A-Z]+)\n\.\n/$1.\n/g; 
    s/([^\n])'s\n/$1\n's\n/g; 
    s/([^\n])n't\n/$1\nn't\n/g; 
    s/([^\n])'re\n/$1\n're\n/g; 
    s/\n\$([^\n])/\n\$\n$1/g; 
    s/([^\n])%\n/$1\n%\n/g; 
    s/Mr\n\.\n/Mr.\n/g; 
    return (split /\n/); 
} 
+0

看看我的回覆我把我的整個代碼..我不把他們的關鍵字搜索@鍵,因爲你可以看到,如果你看看我的編輯代碼... – adrCoder 2014-11-04 09:10:22

+0

@AdrFinance:答案更新。 – choroba 2014-11-04 09:32:08

+0

非常好!非常感謝解決方案離子!所以我把密鑰保存在%計數中,所以每次在第一次找到關鍵字後,關鍵字仍然在計數中,因此每個文件都通過過濾器,對吧?如果我在令牌循環內進行比較,它會比較慢,因爲其他方法使用的是更快的散列? – adrCoder 2014-11-04 09:42:46

0

正則表達式模式匹配將根據子字符串進行匹配。爲避免這種情況,請使用\b來匹配'文字邊界'。

if (($keys[$i] =~ m/\b$tenka\b/) or ($keys[$i] =~ m/\b$tenksba\b/)) { 
+0

這會導致編譯錯誤:找到反斜槓,其位置在move10K1996.pl第38行,靠近「m/\ b $ tenka \ b」或($ keys [$ i] =〜m/\「 )預計在move10K1996.pl第38行,接近「$ tenksba」 \t(在\?之前缺少操作符)如果我在第一個b之後添加/,它仍然會得到沒有/ A的那個... – adrCoder 2014-11-03 16:35:59

+0

您的解釋沒有正則表達式95-B/A不會與只有95-B的字符串匹配,有或沒有字邊界。 – Borodin 2014-11-03 16:55:56

+0

好的,我編輯了我的初始文章,並把我的整個代碼,請看看 – adrCoder 2014-11-04 09:10:39

相關問題