Perl を使用してファイル内のキーワード間のテキストを抽出する

Perl を使用してファイル内のキーワード間のテキストを抽出する

キーワード間のテキストを抽出するにはどうすればよいですか? テキストは txt または json ファイルに保存されます。入力は次のとおりです。「環境とプロジェクトの課題に適応する\n問題を管理する能力、コミュニケーションと影響力、優れたテクノロジーとユーザー エクスペリエンスへの情熱\n優れた組織スキル」

キーワードは「能力」、「スキル」、および「経験」です。出力はこれらのキーワードの間にあるテキストになります。この例では、出力は次のようになります。

問題、コミュニケーション、影響力を管理する優れたテクノロジーとユーザーエクスペリエンスへの情熱\n優れた組織力

正規表現は 4 個または 5 個のキーワードを受け入れる準備ができている必要があります。それは可能ですか?

以下のコードを使用しましたが、テキストが txt ファイルではなくプログラム内にある場合にのみ機能します。これは 2 つのキーワードに対してのみ機能します。複数必要です。

$file = 'C:\Users\Acer Nitro\Desktop\perl\sim.txt';

open(SESAME, $file);
while(<SESAME>)
{
    $text .= $_;
}

close(SESAME);
print $text;

($re=$text)=~s/((\bskill\b)|(\bability\b)|.)/${[')','']}[!$3]\Q$1\E${['(','']}[!$2]/gs;
@$ = (eval{/$re/},$@);
print join"\n",@$ unless $$[-1]=~/unmatched/;

手伝ってもらえますか?

答え1

正規表現を変更する必要があると思います。「\ability」と「\skill」はおそらく必要なものではないでしょう。「\a」は「bell」の文字で、「\s」は空白文字に一致します。

キャプチャしたいテキスト部分は、括弧で囲まれた正規表現の適切な部分と一致させることができます。正規表現全体が一致したら、$1、$2 などを使用して部分的に一致した部分にアクセスできます。たとえば... '(\w+)\s+(ability|skill)\s+(\w+)'

答え2

あなたのスクリプトには多くの誤りがあります。私はそれを書き直して簡素化しました。

#!/usr/bin/perl 
use strict;
use warnings;
use Data::Dumper;

# file to search
my $file = 'C:\Users\Acer Nitro\Desktop\perl\sim.txt';
open my $fh, '<', $file or die "unable to open '$file' for reading: $!";
# read whole file in a single string
undef $/;
my $full = <$fh>;
# search text between keywords
my @found = $full =~ /\b(?:ability|skills|experience)\b\R?\K(.+?)(?=\b(?:ability|skills|experience)\b)/gsi;
# dump the result
print Dumper\@found;    

与えられた例の出力:

$VAR1 = [
          ' to manage issues, communications and influencing ',
          ',Passion for great technology and user ',
          'Exceptional organizational '
        ];

正規表現の説明:

/                       # regex delimiter
    \b                  # word boundary
    (?:                 # non capture group
        ability         # literally
      |                 # OR
        skills          # literally
      |                 # OR
        experience      # literally
    )                   # end group
    \b                  # word boundary
    \R?                 # optional linebreak
    \K                  # forget all we have seen until this position
    (.+?)               # group 1, the text we want
    (?=                 # positive lookahead
        \b              # word boundary
        (?:             # non capture group
            ability     # literally
          |             # OR
            skills      # literally
          |             # OR
            experience  # literally
        )               # end group
        \b              # word boundary
    )                   # end lookahead
/gsi                    # delimiter, global; dot matches newline; case insensitive

関連情報