Usando Perl, como posso mostrar o contexto em torno de um termo de pesquisa nos resultados da pesquisa?

StackOverflow https://stackoverflow.com/questions/616041

  •  03-07-2019
  •  | 
  •  

Pergunta

Eu estou escrevendo um script Perl que está à procura de um termo em grandes porções de texto. O que eu gostaria de mostrar para o usuário é um pequeno subconjunto do texto em torno do termo de pesquisa, de modo que o usuário pode ter contexto de onde este termo de busca é usado. resultados de pesquisa do Google são um bom exemplo do que estou tentando realizar, onde o contexto do termo de pesquisa é exibido sob o título do link.

A minha pesquisa básica está usando este:

if ($text =~ /$search/i ) {
    print "${title}:${text}\n";
}

($ title contém o título do item do termo de pesquisa foi encontrado em) Isto é muito embora, uma vez que às vezes US $ texto vai realizar centenas de linhas de texto.

Este vai ser exibido na web, então eu poderia apenas fornecer o título como um link para o texto real, mas não há nenhum contexto para o usuário.

Eu tentei modificar meu regex para captura de 4 palavras antes e 4 palavras após o termo de pesquisa, mas funcionou em problemas se o termo de pesquisa foi bem no início ou final de $ texto.

O que seria uma boa maneira de conseguir isso? Eu tentei procurar CPAN, porque eu tenho certeza que alguém tem um módulo para isso, mas eu não consigo pensar em termos direita para procurar. Eu faria como para fazer isso sem módulos, se possível, porque recebendo módulos instalados aqui é uma dor. Alguém tem alguma idéia?

Foi útil?

Solução

A sua tentativa inicial de 4 palavras antes / depois não foi muito longe.

Tente:

if ($text =~ /((\S+\s+){0,4})($search)((\s+\S+){0,4})/i) {
    my ($pre, $match, $post) = ($1, $3, $4);
    ...
}

Outras dicas

Você pode usar $ and $' to get the string before and after the match. Then truncate those values appropriately. But as blixtor points out, shlomif is correct to suggest using @ + and @ -to avoid the performance penalty imposed by $ e #' -

$foo =~ /(match)/;

my $match = $1;
#my $before = $`;
#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";

Gostaria de sugerir usando os parâmetros posicionais - @ + e @ -. (Ver perldoc perlvar) para encontrar a posição na seqüência do jogo, e quanto é preciso

Você pode tentar o seguinte:

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;

}

Alguns códigos obviamente omitido, mas isso deve dar-lhe uma ideia da abordagem.

Quanto extrair o título ... Eu acho que esta abordagem não se presta a isso muito bem.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top