Frage

Ich schreibe einen Perl-Skript, das für einen Zeitraum in großen Teilen des Textes sucht. Was ich möchte zurück zu dem Benutzer anzuzeigen ist eine kleine Teilmenge des Textes um den Suchbegriff ein, so dass der Benutzerkontext, wo diese Suche hat Begriff verwendet wird. Google-Suchergebnisse sind ein gutes Beispiel dafür, was ich zu tun versuchen, wo der Kontext des Suchbegriffs wird unter dem Titel des Link angezeigt.

Meine einfache Suche wird mit diesem:

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

($ title enthält den Titel des Elements der Suchbegriff gefunden wurde) Dies ist allerdings zu viel, da manchmal $ text wird Hunderte von Zeilen von Text.

Das wird auf dem Web angezeigt werden, so konnte ich nur den Titel als Link zu dem eigentlichen Text bieten, aber es gibt keinen Kontext für den Benutzer.

Ich habe versucht, meine regex modifizieren 4 Wörter zu erfassen, bevor und 4 Worte nach dem Suchbegriff ein, sondern lief in Probleme, wenn der Suchbegriff am Anfang oder ganz am Ende $ text war.

Was wäre ein guter Weg, um dies zu erreichen? Ich habe versucht CPAN suchen, weil ich bin sicher, dass jemand ein Modul für das hat, aber ich kann nicht denken Sie an die richtigen Begriffe zu suchen. Ich würde wie , dies zu tun, ohne Module, wenn möglich, da Module hier installiert bekommt ein Schmerz ist. Hat jemand irgendwelche Ideen?

War es hilfreich?

Lösung

Ihr erster Versuch 4 Worte vor / war nach nicht zu weit weg.

Versuchen:

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

Andere Tipps

Sie können mit $ 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 $ und #‘-

$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";

Ich würde vorschlagen, die Positionsparameter mit - @ + und @ - (siehe perldoc perlvar) zu finden, die Position in der Zeichenfolge des Spiels, und wie viel es braucht,

.

Sie könnten versuchen, die folgende:

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;

}

offensichtlich Einige Code weggelassen, aber das sollte Ihnen eine Vorstellung von dem Ansatz.

Was den Titel Extrahieren ... Ich denke, dieser Ansatz eignet sich nicht sehr gut dafür.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top