11. Perl で正規表現(3)〜活用例 

   11−1  文字列検索
   11−2  文字列置換
   11−3  対応する文字の置換


11−1  文字列検索

ise.txt から和歌を抜き出してみます。ファイルは D:\ にあるとします。
ise.txt では、伊勢物語の各段を下記のフォーマットで記述してあります。
は全角空白、 は改行コードを意味します。)
C:121:梅の花笠

むかし、男、梅壷より雨にぬれて、人のまかりいづるを見て、
□□うぐひすの花を縫ふてふ笠もがなぬるめる人に着せてかへさむ
返し、
□□うぐひすの花を縫ふてふ笠はいな思ひをつけよほしてかへさむ


和歌の行頭には必ず全角空白が2つあるので、それを利用します。
$. は、処理ファイルから読み込んだ行数をカウントしている特殊変数です。)
◆ コマンドライン
 >perl -ne "if(/^□□/){print $.,':',$_;}" ise.txt
◆ スクリプトの意味
 -n オプション   …… 暗黙の while(<>){ スクリプト } を指定
 if(/^□□/){           …… 行頭に全角空白2つがあったら、
  print $., ':', $_;  ……  行番号と':'と$_を画面出力
 }
実行結果です。(薄黄色の文字の部分が Perl による出力です)
保存が必要であれば、出力先を任意のファイルへリダイレクトしましょう。
 C:\>D:
 
 D:\>perl -ne "if(/^□□/){print $.,':',$_;}" ise.txt
 12:□□春日野の若むらさきのすりごろもしのぶの乱れ限り知られず
 15:□□陸奥のしのぶもぢずりたれゆゑに乱れそめにしわれならなくに
       :
       :
 1282:□□思ふこといはでぞただにやみぬべきわれとひとしき人しなければ
 1288:□□つひにゆく道とはかねて聞きしかど昨日今日とは思はざりを

 D:\>

ところで、処理ファイルにワイルドカードを含んだ文字列を指定しても、 Perl 自体ではそれをファイル名の実リストに展開しません。
UNIX 系OSでは、Perl に処理が渡される前の段階で「シェル」 がファイル名展開をしてから実リストを Perl に渡してくれる (そのために Perl はこの機能を実装する必要がなかった)のですが、 Windows の「コマンドプロンプト」「MS-DOSプロンプト」だと残念ながらそこまでしてはくれないのです。
そのため Windows版 Perl で複数のファイルを処理対象とする場合、 具体的なファイル名を列挙して与えなければなりません。ワイルドカードを指定すると、
 D:\>perl -ne "if(/^□□/){print $.,':',$_;}" *.txt
 Can't open *.txt: Invalid argument.

 D:\>
というエラーが表示されます。


11−2  文字列置換

前章でも少し紹介しましたが、文字列の置換は 変数 =~ s/ / /; というコマンドです。 変数の中の文字列が置き換えられます。
変換元には正規表現が使えます。( ) でくくって部分一致させたパターンを、 置換文字列の中で \1\9 という形で参照することができます。
(秀丸だと \0\9 でした、ちょっと注意が必要です。)
これによって、複雑な置換もわりとすっきりした形で表現することができます。
各章段のタイトル行を抜き出し、希望の形に整形して出力します。 今回はスクリプトをファイル ttl.pl に記述し、それを実行してみます。
◆ コマンドライン
>perl ttl.pl ise.txt   ← Windows9x系
>ttl.pl ise.txt        ← Windows2000/XPならこれでOK
◆ ttl.pl の内容
01:while(<>){
02:     if (/^C:/){
03:         s/C:([0-9]+:)(.+)$/\2……第\1段/;
04:         print;
05:     }
06:}
◆ スクリプトの意味
01:1行ずつ $_ に読み込み、
02:  もしタイトル行だったら、
03:   "C:xxx:タイトル" を "タイトル……第xxx段" に置き換え
04:   置換後の $_ を画面出力
05:  (タイトル行でなかったら06:へ)
06:(01:へ)
実行結果です。(薄黄色の文字の部分が Perl による出力です)
保存が必要であれば、出力先を任意のファイルへリダイレクトしましょう。
 D:\>ttl.pl ise.txt
 初冠……第001段
 西の京の女……第002段
     :
     :
     :
 いはでぞただに……第124段
 つひにゆく道……第125段

 D:\>
スクリプトをファイルに保存してあれば、手軽に繰り返し実行できる (長い1行スクリプトを毎度打ち込むのも面倒なものです)だけでなく、 もし同じ形式のタイトル行を持つテキストがあれば、 それに使い回すこともできます。


11−3  対応する文字の置換


各章段のタイトル行にある半角数字 0,1,2 ・・・ 9 を漢数字 ○、一、二・・・九 に置き換えます。
秀丸などのエディタでは通常、"1" を "一" に置換、"2" を "二" に置換 … を繰り返すしかなく、一度に置換するにはマクロを組むことになります。
SED、AWK、Perl などには「対応する文字で置き換える」という置換命令があり、 一気に処理することができます。
下の例は、半角文字を全角文字に置き換える操作であるため、日本語対応の JPerl でないと正しく動作しません。もちろん半角文字同士であれば、perl.exe でも期待通りの結果を表示することができます。 (Perl 5.8 以降のバージョンでは、Encodeモジュールの活用により、複数文字コード体系を 含む2バイトコードに正しく対応するプログラムも可能です。)
>jperl -pe "tr/0123456789/〇一二三四五六七八九/;" ise.txt
◆ スクリプトの意味
 -p オプション  …… 暗黙の while(<>){スクリプト;print;} を指定
 tr/  0 1 2 3 4 5 6 7 8 9
       ↓↓↓↓↓↓↓↓↓↓     …… 各位置に対応した文字へ置き換え
    /  〇一二三四五六七八九 /;
tr/ / /; のかわりに y/ / /; とすることもできます。

実行結果です。(薄黄色の文字の部分が Perl による出力です)
保存が必要であれば、出力先を任意のファイルへリダイレクトしましょう。
 D:\>jperl -pe "tr/0123456789/〇一二三四五六七八九/;" ise.txt
 T:『伊勢物語』


 C:〇〇一:初冠
   ^^^^^^
  むかし、男、初冠して、奈良の京、春日の里に、しるよしして、狩にいに
       :
       :
       :
 C:一二五:つひにゆく道
   ^^^^^^
  昔、男わづらひて、心地死ぬべくおぼえければ、
   つひにゆく道とはかねて聞きしかど昨日今日とは思はざりしを

 D:\>