teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

3

追記

2021/09/19 23:49

投稿

KojiDoi
KojiDoi

スコア13727

answer CHANGED
@@ -40,4 +40,59 @@
40
40
  ```
41
41
  # フィルタコマンドとして機能する
42
42
  perl test.pl < input_utf8.txt > output_sjis.txt
43
- ```
43
+ ```
44
+
45
+ # 2021-09-20追記
46
+
47
+ ## 複数文字対応の置換
48
+
49
+ tr演算子は1文字対応の変換しかできません。複数文字対複数文字の置換にはs演算子を使います。
50
+
51
+ コーディングスタイルはいろいろ考えられると思いますが、変換表のメンテンナンスがしやすいであろうスタイルで参考コードを書いてみました。
52
+
53
+ ```
54
+ #test.pl
55
+
56
+ use strict;
57
+ use warnings;
58
+ use utf8;
59
+
60
+ binmode STDOUT, ":utf8";
61
+
62
+ my %t; # 変換表を持たせるハッシュ
63
+ while(<DATA>){ # 末尾の変換表を読み込む
64
+ my($from, $to) = split; # 各行のスペースの前が変換前、後ろが変換後の文字列
65
+ $t{$from} = $to; # $t{'林檎'}='りんご';
66
+ }
67
+
68
+ # サンプル文字列
69
+ my $a="林檎と蜜柑。夏蜜柑。姫林檎。";
70
+
71
+ print "原文: $a\n";
72
+ foreach my $from (keys %t){
73
+ $a=~s/$from/$t{$from}/g;
74
+ }
75
+ print "改訂: $a";
76
+
77
+ __DATA__
78
+ 林檎 りんご
79
+ 蜜柑 みかん
80
+ 柿 かき
81
+ 桃 もも
82
+ 木通 あけび
83
+ 西瓜 すいか
84
+ ```
85
+
86
+ ```
87
+ $ perl test.pl
88
+ ```
89
+
90
+ ## 参考文献
91
+
92
+ 実は[Perlの公式ドキュメント、モジュールドキュメントを日本語に翻訳したもの](https://perldoc.jp/)が無償公開されており、これをチェックするのが一番確実だったりします。バージョンごとの違いをすぐに比較できるのもありがたいところです。
93
+
94
+ 書籍では『リャマ本』と通称される『[O'Reilly Japan - 初めてのPerl 第7版](https://www.oreilly.co.jp/books/9784873118246/)』を挙げておきます。
95
+
96
+ バイブル視されている本に、同じ出版社から出ている『ラクダ本』こと[『プログラミングPerl』](https://amzn.to/3EwEAmA)というのがありますが、やや古くなっていることと、内容がそれなりに難しく、perl初心者には少し面倒な部分があるようにあるうえ、結構お高いため、積極的にはお勧めしません。
97
+
98
+ ほんとうは本屋に行って波長に合いそうなものを立ち読みして読み比べてみるのが一番なんですが。

2

注釈

2021/09/19 23:49

投稿

KojiDoi
KojiDoi

スコア13727

answer CHANGED
@@ -22,20 +22,22 @@
22
22
 
23
23
  ```
24
24
  # test.pl
25
- use utf8;
25
+ use utf8; # コード中にUTF-8のリテラル(平たく言えば全角の文字列)を直接書き込むときは指定しなければならない。それらの文字を「内部コード」化して取り扱うことを指示するもの
26
- use strict;
26
+ use strict; # おまじないとして必ず書く
27
- use warnings;
27
+ use warnings; # おまじないとして必ず書く
28
28
 
29
- binmode STDOUT, ':encoding(cp932)';
29
+ binmode STDOUT, ':encoding(cp932)'; # 標準出力は内部コードからシフトJISに変換される
30
- binmode STDIN, ':utf8';
30
+ binmode STDIN, ':utf8'; # 標準入力はUTF-8から内部コードに変換される
31
31
 
32
32
  while(<>){
33
+ # 標準入力から1行読み取って$_に代入する
33
- tr{俠俱剝吞啞}
34
+ tr{俠俱剝吞啞} # 変換前の非互換な文字たち
34
- {侠倶剥呑唖};
35
+ {侠倶剥呑唖}; # 上記それぞれに対応する「安全な」文字。tr{abc}{ABC}はtr/abc/ABC/と同義。2行に渡って書けるので読みやすい。$_を対象に、trの最初の引数に列挙された文字を後ろの引数に指定された文字にすべて置換する。
35
- print;
36
+ print; # 標準出力に出力。最初のbincode設定により、シフトjisで出力される。
36
37
  }
37
38
  ```
38
39
 
39
40
  ```
41
+ # フィルタコマンドとして機能する
40
42
  perl test.pl < input_utf8.txt > output_sjis.txt
41
43
  ```

1

追記

2021/09/10 01:25

投稿

KojiDoi
KojiDoi

スコア13727

answer CHANGED
@@ -15,4 +15,27 @@
15
15
 
16
16
  繰り返しですが、こうした操作は「内部コード化」した文字列以外に対して一切試みてはいけません。また、普通の状況ではfrom_to()を使う局面はありません。何をしたいのかが完璧に理解できている自信がない状況ではおそらく使うべきではないでしょう。
17
17
 
18
- 巷にあふれる解説(とくに個人ブログ)は、古い情報に基づいていたり明らかに誤解していたりのいい加減なものばかりなので、あまり当てにしないほうがいいです。ブログで信用に足ると安心しておすすめできるのはDan Kogaiさんの記事ぐらいのものです。
18
+ 巷にあふれる解説(とくに個人ブログ)は、古い情報に基づいていたり明らかに誤解していたりのいい加減なものばかりなので、あまり当てにしないほうがいいです。ブログで信用に足ると安心しておすすめできるのはDan Kogaiさんの記事ぐらいのものです。
19
+
20
+ # サンプルコード
21
+ とりあえずサンプルコードを示します。utf-8で書かれているテキストを標準入力から読み込み、cp932非対応な文字の幾種類かをとりあえず「大丈夫な」文字に変換した上で、cp932に変換して出力するというものです。
22
+
23
+ ```
24
+ # test.pl
25
+ use utf8;
26
+ use strict;
27
+ use warnings;
28
+
29
+ binmode STDOUT, ':encoding(cp932)';
30
+ binmode STDIN, ':utf8';
31
+
32
+ while(<>){
33
+ tr{俠俱剝吞啞}
34
+ {侠倶剥呑唖};
35
+ print;
36
+ }
37
+ ```
38
+
39
+ ```
40
+ perl test.pl < input_utf8.txt > output_sjis.txt
41
+ ```