2016-05-27 7 views
2

私はこのPerlスクリプト(Jeff Schallerのおかげで)を使って2つのCSVファイルのタイトルフィールドに3つ以上の単語をマッチさせています。ここ 元の質問:1つの問題は、私は私がある微調整したいことを見つけた、私のテスト中perlスクリプトを修正して、単語ベースで単語に一致させるようにしました。

#!/bin/perl 

my @csv2 =(); 
open CSV2, "<csv2" or die; 
@csv2=<CSV2>; 
close CSV2; 

my %csv2hash =(); 
for (@csv2) { 
    chomp; 
    my ($title) = $_ =~ /^.+?,\s*([^,]+?),/; #/ match the title 
    $csv2hash{$_} = $title; 
} 

open CSV1, "<csv1" or die; 
while (<CSV1>) { 
    chomp; 
    my ($title) = $_ =~ /^.+?,\s*([^,]+?),/; #/ match the title 
    my @titlewords = split /\s+/, $title; #/ get words 

    my @new;       #add exception words which shouldn't be matched 
    foreach my $t (@titlewords){ 
    push(@new, $t) if $t !~ /^(and|if|where)$/i; 
    } 
    @titlewords = @new; 
    my $desired = 3; 
    my $matched = 0; 
    foreach my $csv2 (keys %csv2hash) { 
    my $count = 0; 
    my $value = $csv2hash{$csv2}; 
    foreach my $word (@titlewords) { 
     ++$count if $value =~ /\b$word\b/i; 
     last if $count >= $desired; 
    } 
    if ($count >= $desired) { 
     print "$csv2\n"; 
     ++$matched; 
    } 
    } 
    print "$_\n" if $matched; 
} 
close CSV1; 

https://unix.stackexchange.com/questions/283942/matching-3-or-more-words-from-fields-in-separate-csv-files?noredirect=1#comment494461_283942

は、私はまた、meuhからのアドバイス、次のいくつかの例外機能を追加しましたcsv2にtheのような共通の単語が1つ含まれている場合、csv1に3回以上複製されていれば、3つの正の一致が見つかります。明確にする:

をCSV1が含まれている場合:

1216454,the important people feel the same way as the others, 15445454, 45445645 

^すなわちCSV2が含まれている場合theの3 insatncesは、上記の行

にあります

14564564,the tallest man on earth,546456,47878787 

^すなわち、1つありますこの行のtheのインスタンス

次に、ファイルの1つに一致する単語のインスタンスが1つしかないため、マッチングとして分類される単語は1つだけとし、出力する必要はありません。

しかし場合:

1216454,the important people feel the same way as the others,15445454, 45445645 

とCSV2が含まれる:

CSV1が含ま

15456456,the only way the man can sing the blues,444545,454545 

そして、ワードtheの各々(すなわち、3つのインスタンス三個の一致する単語が存在するように各タイトルで3つ以上の一致する単語の数に基づいてこれを一致タイトルとして分類し、出力を生成します:

1216454,the important people feel the same way as the others,15445454, 45445645 
15456456,the only way the man can sing the blues,444545,454545 
I次いで、CSV内のワード、及び他のCSV内の同じ単語の複数のインスタンスの1つのインスタンスが存在する場合には、一方のみ一致として分類されるようにスクリプトを修正したい

。しかし、両方のファイルにtheという単語が3つ存在する場合、3つの一致として分類されます。基本的には、マッチを単語ベースの単語にしたいと思います。 これ以外のスクリプトに関するものはすべて完璧ですので、これ以外のすべてに満足しているので、私は描画ボードに完全に戻っていません。 私はそれを説明したことを願っています。

+0

あなたの質問を編集して、解析する必要がある入力と表示したい出力の例を教えてください。コンテキストに関する以前の質問へのリンクも役立ちます。あなたが望むのは、同じ単語の繰り返しを無視して、ユニークなマッチだけを数えることです。あれは正しいですか? – terdon

答えて

1

あなただけのユニークなマッチをカウントする弱々しい場合は、あなたがcsv2のために行うと同じように、csv1から単語を収集し、その後も個別に各単語の出現をカウントする代わりに、リストのハッシュを使用することができます。

#!/usr/bin/env perl 

my @csv2 =(); 
open CSV2, "<csv2" or die; 
@csv2=<CSV2>; 
close CSV2; 

my %csv2hash =(); 
for (@csv2) { 
    chomp; 
    my ($title) = $_ =~ /^.+?,\s*([^,]+?),/; #/ match the title 
    $csv2hash{$_} = $title; 
} 

open CSV1, "<csv1" or die; 
while (<CSV1>) { 
    chomp; 
    my ($title) = $_ =~ /^.+?,\s*([^,]+?),/; #/ match the title 
    my %words; 
    $words{$_}++ for split /\s+/, $title; #/ get words 
    ## Collect unique words 
    my @titlewords = keys(%words); 
    my @new;       #add exception words which shouldn't be matched 
    foreach my $t (@titlewords){ 
     push(@new, $t) if $t !~ /^(and|if|where)$/i; 
    } 
    @titlewords = @new; 
    my $desired = 3; 
    my $matched = 0; 
    foreach my $csv2 (keys %csv2hash) { 
    my $count = 0; 
    my $value = $csv2hash{$csv2}; 
    foreach my $word (@titlewords) { 
      my @matches = ($value=~/\b$word\b/ig); 
      my $numIncsv2 = scalar(@matches); 
      @matches  = ($title=~/\b$word\b/ig); 
      my $numIncsv1 = scalar(@matches); 
      ++$count if $value =~ /\b$word\b/i; 
      if ($count >= $desired || ($numIncsv1 >= $desired && $numIncsv2 >= $desired)) { 
       $count = $desired+1; 
       last; 
      } 
    } 
    if ($count >= $desired) { 
     print "$csv2\n"; 
     ++$matched; 
    } 
    } 
    print "$_\n" if $matched; 
} 
close CSV1; 
+0

こんにちは、これは私が確かに達成したいものに近いですが、私の質問をサンプル出力で編集してみてください。現時点では、あなたの修正は与えられた単語の1インスタンスにしか一致しません。しかし、両方のファイルに同じ単語の複数のインスタンスが含まれている場合は、それらの単語を一致としてカウントします。 – nmh

+0

@nmh OK、更新されたスクリプトを参照してください。次回は、われわれが理解できるように十分な例を含めるようにしてください。すべての可能性のある状況を再現するサンプルデータを表示し、必要な出力を説明します。また、この種の複雑な質問は実際にはサイトには適していません。あなたの質問に対する答えが完全なスクリプトである場合は、問題を小さなチャンクに分割して、自分でスクリプトを書くことができます。 – terdon

+0

わかりました。私のオリジナルの質問は、grepを使ってみることから始めましたが、私が知っているperlスクリプトに変わってしまいました!あなたの助けをありがとう、私はしようとし、将来的に私のクエリを分割します。 – nmh

関連する問題