باستخدام بيرل، كيف يمكنني إظهار إطار حول مصطلح البحث في نتائج البحث؟

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

  •  03-07-2019
  •  | 
  •  

سؤال

وأنا أكتب نصي بيرل التي تبحث عن مصطلح في أجزاء كبيرة من النص. ما أود أن عرضه إلى المستخدم هو مجموعة فرعية صغيرة من النص حول مصطلح البحث، بحيث يمكن للمستخدم الحصول على سياق حيث يتم استخدام هذا المصطلح البحث. نتائج بحث Google هي خير مثال على ما أحاول تحقيقه، حيث يتم عرض سياق مصطلح البحث تحت عنوان الارتباط.

وبحثي الأساسي يستخدم هذا:

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

و($ عنوان يحتوي على عنوان هذا البند تم العثور على مصطلح البحث في) هذا كثير جدا على الرغم من، في بعض الأحيان منذ $ النص سوف يكون عقد مئات من أسطر من النص.

وهذا هو الذهاب للظهور على شبكة الإنترنت، حتى أتمكن من مجرد توفير عنوان كحلقة وصل إلى النص الفعلي، ولكن ليس هناك إطار للمستخدم.

وحاولت تعديل بلدي التعابير المنطقية للقبض على 4 كلمات قبل و4 كلمات بعد البحث الطويل، لكنها واجهت مشاكل إذا كان مصطلح البحث في البداية أو النهاية من نص $.

وماذا سيكون وسيلة جيدة لتحقيق ذلك؟ حاولت البحث كبان لأنني متأكد من شخص ما لديه وحدة لهذا، ولكن لا أستطيع أن أفكر من حيث الحق في البحث عنها. وأود أن <م> مثل القيام بذلك دون وحدات إذا أمكن، لأن الحصول على تركيب وحدات هنا هو الألم. هل لديها أي أفكار؟

هل كانت مفيدة؟

المحلول

ومحاولة الأولي بقيمة 4 كلمات قبل / بعد لم يكن بعيدا جدا.

وجرب:

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

نصائح أخرى

ويمكنك استخدام $ 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 $ و# '-

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

وأود أن أقترح استخدام المعلمات الموضعية - @ + و @- (انظر 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;

}

وبعض كود حذف الواضح، ولكن هذا يجب أن تعطيك فكرة عن هذا النهج.

وبقدر استخراج العنوان ... وأعتقد أن هذا النهج لا تصلح لذلك جيدا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top