blog20100901

2013/08/20 - プログラミング言語 Perl にまつわる etc. - Perl monger
参考 : perldoc, perldoc.jp, search.cpan.org, perldoc.perl.org ...
「 初めての Perl 第 6 版 」(オライリー・ジャパン発行 ISBN978-4-87311-567-2) 」
「 続・初めての Perl 改訂版 」(オライリー・ジャパン発行 ISBN4-87311-305-9) 」
「 Effective Perl 第 2 版 」(翔泳社発行 ISBN978-4-7981-3981-4) 」 ... etc,.

Perl Perl_4

Perl 部分文字列の抽出と置換 substr 日本語 (0x246)

Perl 部分文字列の抽出と置換  substr 日本語 (0x246)

目次 - Perl Index



Theme



Perl について、復習を兼ねて断片的な情報を掲載して行く連載その 0x246 回。

Perl で、部分文字列を操作する関数「 substr 」を、日本語文字列 ( マルチバイト文字列 ) で扱う方法を確認する。


マルチバイト文字列の扱い「 心得 」



(0x243) と (0x244) では、Perl で日本語文字列 ( マルチバイト文字列 ) を扱う場合の基本を、次のように確認しました。

  ・プログラムファイルの文字コードは「 UTF-8 」とする。

  ・「 use utf8 」を利用して文字列リテラルを「 flagged utf8 」とする。

  ・外部から入力された文字列は デコード して「 flagged utf8 」とする。

  ・プログラムでは文字列を「 flagged utf8 」で処理する。

  ・外部へ出力する文字列は エンコード して任意の文字コードとする。

これらの基本を心得としてふまえて、関数「 substr 」で日本語文字列を操作してみます。


関数「 substr 」で日本語文字列を扱う



関数「 substr 」でマルチバイト文字列を利用するためのプログラムコードは次のものです。心得に忠実に基本的な処理を書いてみました。


# 文字列リテラルを flagged utf8 にする
use utf8;

# 文字列の エンコード / デコード を行うモジュール
use Encode;

# 文字列リテラル ( flagged utf8 ) をセット
my $string = "ハローワールド。ハローパール。";

# OFFSET 0 から 3 文字分を取り出す
my $substr = substr($string, 0, 3);

# 出力に備えて flagged utf8 を UTF-8 にエンコードする
my $enc_substr = encode('utf-8', $substr);

# UTF-8 で出力 ( ハロー )
print "$enc_substr\n";



これにより、print 文では文字列「 ハロー 」が出力されます。

13 行目で「 UTF-8 」へのエンコード処理を行わず、「 flagged utf8 」のまま文字列を出力すると、警告メッセージ「 Wide character in print at ... 」が出力されます。


関数「 index 」も加えて置換処理をする



関数「 substr 」の第 4 引数「 REPLACE 」を利用してマルチバイト文字列の置き換えを行います。 ここでは関数「 index 」も追加してみました。


use utf8;
use Encode;

my $string = "ハローワールド。ハローパール。";

# ワールド を マイフレンド に置換
substr($string, index($string, 'ワールド') , 4, 'マイフレンド');

my $enc_string = encode('utf-8', $string);

# ハローマイフレンド。ハローパール。
print "$enc_string\n";



プログラム内の処理は「 flagged utf8 」で行い、出力時に「 UTF-8 」へのエンコードを行っているので、7 行目の文字列置換も 12 行目の print 文での出力も問題なく完了します。


マルチバイト文字列の入力を処理する



外部からマルチバイト文字列の入力を受け付けて、処理してみます。

入力は、「 文字列 」,「 部分文字列 」,「 置換文字列 」を受け付けます。

外部から「 部分文字列 」を受け付ける場合は、関数「 substr 」の第 3 引数「 LENGTH 」の値が分からないので、関数「 length 」を利用して文字列の長さを取得するようにしています。

関数「 lnegth 」は (0x53) 等で少し確認しています。


use utf8;
use Encode;

# 入力受付 ( 外部からは UTF-8 で入力される )
print "string: ";
chomp(my $string = <STDIN>);
print "substring: ";
chomp(my $substr = <STDIN>);
print "replace: ";
chomp(my $replace = <STDIN>);

# UTF-8 を flagged utf8 にデコード
my $dec_string = decode('utf-8', $string);
my $dec_substr = decode('utf-8', $substr);
my $dec_replace = decode('utf-8', $replace);

# flagge utf8 の文字列から長さを取得
my $length = length($dec_substr);

# 文字列はすべて flagged utf8
substr($dec_string, index($dec_string, $dec_substr ), $length, $dec_replace);

# 出力前に UTF-8 にエンコード
my $enc_string = encode('utf-8', $dec_string);

print "$enc_string\n";



このプログラムコードをファイル名「 substr_replace.pl 」で保存して実行すると次のような結果が得られます。


$ perl substr_replace.pl
string: ハローワールド
substring: ワールド
replace: パール
ハローパール



成功です。


0x246 -> 0x247 へ



Perl での日本語処理がだいぶこなれてきました。僕にとっては、「 プログラムファイルは UTF-8 で作成・保存する 」するという知識がクリティカルだったように思います。

なお、デコード / エンコード に利用しているモジュール「 Encode.pm 」には、より便利な関数が様々に用意されています。興味のある方は Encode.pm - CPAN 等を確認してみてください。

また、Perl での デコード / エンコード には「 Encode.pm 」以外の選択肢も用意されています。まずは、Perl Unicode FAQ - perldoc.jp あたりを読んで見るとよいかもしれません。

次回は、「 printf 」によく似た関数「 sprintf 」を確認します。


参考情報は書籍「 初めての Perl 第 6 版 」を中心に perldoc, Wikipedia および各 Web サイト。それと詳しい先輩。

目次 - Perl Index





















同じカテゴリー(Perl)の記事
 Perl mp2 翻訳 Web コンテンツ圧縮の FAQ (d228) (2023-10-11 23:49)
 Perl mp2 翻訳 既知のブラウザのバグの回避策をいくつか (d227) (2023-05-26 15:41)
 Perl mp2 翻訳 Perl と Apache でのキュートなトリック (d226) (2023-05-19 17:05)
 Perl mp2 翻訳 テンプレートシステムの選択 (d225) (2022-08-15 22:23)
 Perl mp2 翻訳 大規模 E コマースサイトの構築 (d224) (2022-06-15 20:43)
 Perl mp2 翻訳 チュートリアル (d223) (2022-06-15 20:42)

Llama
リャマ
TI-DA
てぃーだブログ
プロフィール
セラ (perlackline)
セラ (perlackline)
QRコード
QRCODE
オーナーへメッセージ

PAGE TOP ▲