例題 3テキストファイルを入力として, その中で m で始まって s で終わる単語のみを出力する Perl スクリプト find_word.pl を作りなさい.
(実行例)
解答例while ( $line = <> ){ @words = split(/\b/, $line); foreach $w ( @words ){ if ( $w =~ /^m.*s$/ ){ print $w, "\n"; } } } 解説(1)単語に分割前回学んだ split 演算子を再び使用する. 今回は「単語の区切り」をパターンとして表現する必要があるが, Perl では特別に
\b
が単語の区切りを表すことになっており,これを利用すればよい.
例えば,上述の回答例から if 文による条件分岐を無視し (# でコメントアウト),
while ( $line = <> ){
@words = split(/\b/, $line);
foreach $w ( @words ){
# if ( $w =~ /^m.*s$/ ){
print $w, "\n";
# }
}
}
これを実行してみると split の働きが見えてくる:
$ perl find_word.pl ex3.txt Given the central .....(中略) process improvement .いちいち改行が入っているように見えるが, これは単語と単語の間の空白も切り出されているためである. "Given the central " → 「Given」, 「(空白)」, 「the」, 「(空白)」,「central」
(2)m で始まって s で終わるパターン
while ( $line = <> ){
@words = split(/\b/, $line);
foreach $w ( @words ){
if ( $w =~ /^m.*s$/ ){
print $w, "\n";
}
}
}
ここではパターンの記述に三つのポイントがある:
特別な表記として
^
は文字列の先頭を意味する.
それゆえ ^m は文字列が「m で始まる」を意味する.
(2-2)s で終わる
$
は文字列の末尾を意味する(ただし,末尾が改行文字の場合はその前).
それゆえ s$ は文字列が「s で終わる」を意味する.
(2-3)任意の文字列
^ms$と書けば「 m で始まって s で終わる」を意味するように見えるが, これは「ms」という単語にしかマッチしない. m と s の間には任意の文字列が入ってもよいので, これについても書く必要がある. 特別な表記として
. (ピリオド)
は任意の文字(つまり何でもよい)を意味する.
よって, .* は「任意の文字が 0 個以上」=「任意の文字列」を意味する.
それゆえ,総合的には
^m.*s$
と書くことで目的のパターン「m で始まり s で終わる」を表現できる.
既に他の科目で学んだ内容であろうとは思うが,
この種のパターン表現を正規表現という.
|