2011-01-31 11 views
0

私はPerlでこれをやっています。 私はいくつかの段落と61の文章を含むテキストファイルを持っています。 まず、私はすべてやっで支障がないコマンドラインで入力された一連の単語を一致させる必要があります。文字列の一致数のカウントだけでなく、一致する文の判定

my $input = $ARGV[0]; 
$file =~ m/$input/gi; 

残念ながら、いくつかのwrinkles-がある 入力のためにすることができ1複数のアイテムと 2.複数のアイテムは異なる行に配置できます。

例を示します: 3つの文が "fall | election | 2009"のパターンに一致します。文章は次のとおりです。

4「私たちは選挙を嫌う」 16: "犬はバルコニーから落ちて負傷した。" 24「2009年の秋の選挙はありません」

この場合、見つかったプログラムは、秋、選挙、または2009年を含む文書内の3つのセンテンスをカウントしました。

私の質問は2倍です: 入力が表示される文章の数をどのように数えますか?私は正規表現では非常に不慣れですが、デフォルトのマッチは、ファイル内で発生した最初のフォール、選挙、または2009年の出現と一致し、個々の単語がいくつあるかを数えないと考えていました。それらを追加します。私は正規表現で数えることを全く理解していないので、こんなに悩んでいます。

私の質問の2番目の部分は、入力が見つかった文(行4にある選挙)と、入力がある文全体をどのように抽出するのかを最初に見つける方法に関係します。最初のifを使用して行われます。文字列内で入力と一致するものがあれば、新しいスカラーはテキストファイル=〜と置き換えられますか?文の...私は完全に確信しています。

編集:私は実際にこれを実行している完全に解析されたHTML文書を持っています。印刷された場合、1つの例の出力は "ジャーナルはFacebook上にあります!ここのページをチェックしてくださいそれは進行中の作業であり、私たちはあなたのご意見をお待ちしております。 "

私のコマンドラインは次のようになっています:perlこのコマンドを実行すると、以下のようなメッセージが表示されます。 WebScan.pl情報|作者WebPage000.htm

私は前述のように、Webページを解析し、すべてのタグを削除してテキストだけを残しました。今、私は入力を見つけなければなりません。この場合、入力は「情報」または「ライター」です。私はファイルのテキスト内で何回出現するのかを知る必要があります(2)ので、どの文が出現するのか(それぞれ5と6)私はこれまであなたに私のコードが表示されます:

use strict; 
use warnings; 
my $file; 
open (FILENAME, $ARGV[1]); 
$file = do { local $/; <FILENAME> }; 

$file =~ s{ 
    <    # open tag 
    (?:    # open group (A) 
    (!--) |  # comment (1) or 
    (\?) |  # another comment (2) or 
    (?i:   # open group (B) for /i 
     (   #  one of start tags 
     SCRIPT | #  for which 
     APPLET | #  must be skipped 
     OBJECT | #  all content 
     STYLE  #  to correspond 
    )   #  end tag (3) 
    ) |   # close group (B), or 
    ([!/A-Za-z]) # one of these chars, remember in (4) 
)    # close group (A) 
    (?(4)   # if previous case is (4) 
    (?:   # open group (C) 
     (?!   #  and next is not : (D) 
     [\s=]  #  \s or "=" 
     ["`']  #  with open quotes 
    )   #  close (D) 
     [^>] |  #  and not close tag or 
     [\s=]  #  \s or "=" with 
     `[^`]*` | #  something in quotes ` or 
     [\s=]  #  \s or "=" with 
     '[^']*' | #  something in quotes ' or 
     [\s=]  #  \s or "=" with 
     "[^"]*"  #  something in quotes " 
    )*   # repeat (C) 0 or more times 
    |    # else (if previous case is not (4)) 
    .*?   # minimum of any chars 
)    # end if previous char is (4) 
    (?(1)   # if comment (1) 
    (?<=--)  # wait for "--" 
)    # end if comment (1) 
    (?(2)   # if another comment (2) 
    (?<=\?)  # wait for "?" 
)    # end if another comment (2) 
    (?(3)   # if one of tags-containers (3) 
    </   # wait for end 
    (?i:\3)  # of this tag 
    (?:\s[^>]*)? # skip junk to ">" 
)    # end if (3) 
    >    # tag closed 
}{}gsx;   # STRIP THIS TAG 
$file =~ s/&nbsp//gi; 
$file =~ s/&#160//gi; 
$file =~ s/;//gi; 

$file =~ s/[\h\v]+/ /g; 

my $count = $file =~ s/((^|\s)\S)/$2/g; 
my $sentencecount = $file =~ s/((^|\s)\S).*?(\.|\?|\!)/$1/g; 

print "Input file $ARGV[1] contains $sentencecount sentences and $count words."; 

だから、私はキーワードが出現する回数を数え、[0]キーワードとして、テキスト・ファイルを検索$ ARGVを使用して、にPerlを必要とします。次に、キーワードがどのような文章で表示されているか(つまり、文章全体を印刷する)とその文章の番号を述べる必要があります。

答えて

-1

編集更新質問

オーケーを一致させるには、私は自明の理で始めてみましょう:自分でHTMLを解析しようとしないでください。 HTML::TreeBuilderはあなたの友人です。

正規表現では、perlfaq6は非常に優れた情報源です。

次のサンプルは、次の構文で動作します。perl WebScan.pl --regex="information|writers" --filename=WebPage000.htm

段落とその一致のリストを出力します。

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

use HTML::TreeBuilder; 
use Data::Dumper; 
use Getopt::Long; 

my @regexes; 
my $filename; 
GetOptions('regex=s' => \@regexes, 'filename=s' => \$filename); 

my $tb = HTML::TreeBuilder->new_from_file($filename); 
$tb->normalize_content; 

my @patterns = map { qr/$_/ } @regexes; 

my @all; 
foreach my $node ($tb->find_by_tag_name('p', 'pre', 'blockquote')) { 
    my $text = $node->as_text; 
    my @matches; 
    foreach my $r (@patterns) { 
     while ($text =~ /$r/gi) { 
      push @matches, $&; 
     } 
    } 
    push @all, { paragraph => $text, matches => \@matches } if @matches; 
} 

foreach (@all) { 
    print "Paragraph:\n\t$_->{paragraph}\nMatches:\n\t", join(', ', @{$_->{matches}}), "\n"; 
} 

うまくいけば、正しい方向を指すことができます。

+0

私はうまくいけば物事をより明確にするために私の質問を編集しました。コードは私が望むものと非常によく似ていますが、実装方法がわかりません。 – Sheldon

1

あなたの文章を区切っているかどうかは分かりません(または分割基準がある場合)。問題の権利を理解していればそうであれば、そして、あなたはこのような何かを行うことができます。

@words = qw/hi bye 2009 a*d/; 
@lines = ('Lets see , hi ', 
' hi hi hi ', 
' asdadasdas ', 
'a2009a', 
'hi bye'); 

$pattern=""; 
foreach $word (@words) { 
    $pattern .= quotemeta($word) . '|'; 
} 
chop $pattern; # chop last | 
print "pattern='$pattern'\n"; 

$cont = 0; 
foreach $line (@lines) { 
    $cont++ if $line =~ /$pattern/o; 
} 

printf "$cont/%d lines matched\n",scalar(@lines); 

私は私の例のように、我々はいけない(言葉で一部の特殊文字があるだけの場合にはエスケープquotemetaのパターンを構築します一致させたい)。

関連する問題