Perlを使用して、検索結果で検索語の前後のコンテキストを表示するにはどうすればよいですか?
-
03-07-2019 - |
質問
テキストの大部分で用語を検索するPerlスクリプトを書いています。ユーザーに表示したいのは、検索用語の周りのテキストの小さなサブセットです。そのため、ユーザーはこの検索用語が使用されている場所のコンテキストを持つことができます。 Google検索結果は、私が達成しようとしていることの良い例です。検索用語のコンテキストはリンクのタイトルの下に表示されます。
基本的な検索ではこれを使用しています:
if ($text =~ /$search/i ) {
print "${title}:${text}\n";
}
($ titleには、検索語が見つかったアイテムのタイトルが含まれます) ただし、$ textには数百行のテキストが含まれることがあるため、これは多すぎます。
これはWeb上に表示されるので、タイトルを実際のテキストへのリンクとして提供できますが、ユーザーのコンテキストはありません。
正規表現を変更して、検索語の前後4語をキャプチャしようとしましたが、検索語が$ textの先頭または末尾にある場合に問題が発生しました。
これを達成する良い方法は何でしょうか?誰かがこのためのモジュールを持っていると確信しているので、CPANを検索しようとしましたが、検索する適切な用語を考えることができません。ここでモジュールをインストールするのは苦痛なので、可能な場合はモジュールなしでこれを行うことを好きにします。誰にもアイデアはありますか?
解決
前後4ワードでの最初の試行はそれほど遠くありませんでした。
試してください:
if ($text =~ /((\S+\s+){0,4})($search)((\s+\S+){0,4})/i) {
my ($pre, $match, $post) = ($1, $3, $4);
...
}
他のヒント
$ と$ 'を使用して、一致の前後の文字列を取得できます。次に、これらの値を適切に切り捨てます。しかし、blixtorが指摘しているように、shlomifは、
@ + and
@-を使用して、$
および# '-
$foo =~ /(match)/;
my $match = $1;
#my $before = $ と$ 'を使用して、一致の前後の文字列を取得できます。次に、これらの値を適切に切り捨てます。しかし、blixtorが指摘しているように、shlomifは、
@ + and
@-を使用して、$
および# '-
;
#my $after = ;
my $before = substr($foo, 0, $-[0]);
my $after = substr($foo, <*>[0]);
$after =~ s/((?:(?:\w+)(?:\W+)){4}).*/$1/;
$before = reverse $before; # reverse the string to limit backtracking.
$before =~ s/((?:(?:\W+)(?:\w+)){4}).*/$1/;
$before = reverse $before;
print "$before -> $match <- $after\n";
位置パラメータ-@ +および@-(perldoc perlvarを参照)を使用して、一致の文字列内の位置とその所要量を見つけることをお勧めします。
次を試すことができます:
if ($text =~ /(.*)$search(.*)/i ) {
my @before_words = split ' ', $1;
my @after_words = split ' ',$2;
my $before_str = get_last_x_words_from_array(@before_words);
my $after_str = get_first_x_words_from_array(@after_words);
print $before_str . ' ' . $search . ' ' . $after_str;
}
一部のコードは明らかに省略されていますが、これによりアプローチのアイデアが得られるはずです。
タイトルを抽出する限り...このアプローチは、それ自体にはあまり向いていないと思います。