燈明ブログ

現状は小池啓仁の応援ブログ

Perlでテキストファイル内の検索文字列がある行数を求めるには

たとえば、テキストファイルを読み込んで、とある文字列を検索し、それがヒットしたテキスト内の行数を求めたい場合があったとします。
以下は、そんな場合のサンプルです。
検索文字列『小池啓仁』があるテキスト内の行数を取得します。
ただし、このサンプルでは、ファイルI/Oは割愛し、すでにテキストファイルの内容が$strTextに入っているものとしています。

◆サンプル

use strict;
use warnings;
use utf8;
binmode STDOUT, ':encoding(shiftjis)';

my $strText = << "END_OF_TEXT";
1234567890
ABCDEFGHIJ
1234567890
ABCDEFGHIJ
12小池啓仁AB
1234567890
ABCDEFGHIJ
END_OF_TEXT

my $linecnt;

if ($strText =~ /小池啓仁/) {
   $linecnt = scalar(() = ($` =~ /\n/g)) + 1;
   print "検索文字『小池啓仁』にヒットした行数:$linecnt \n";
}

◆解説

  • 『$strText =~ /小池啓仁/』で、検索文字列がヒットするかを求めます。
  • 『$`』は、検索文字列にヒットした直前(検索文字列は含まない)までの文字列です。
  • 『() = ($` =~ /\n/g)』は、直前文字列を改行『\n』ですべて検索『gオプション』して空配列『()』に代入します。
  • 『scalar(() = ($` =~ /\n/g))』は、空配列に代入すると要素は捨てられますが、要素数は取得が出来るのです。
  • 『scalar(() = ($` =~ /\n/g)) + 1』の『+ 1』は、検索文字『小池啓仁』のある行分を加算しています。

◆補足

  • 『use utf8;』は、テキスト(読み込んだファイルもプログラムソースも)の文字コードはutf8を想定しています。
  • 『binmode STDOUT, ':encoding(shiftjis)';』は、標準出力の文字コードはshiftjisを想定しています。