質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Perl

Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

置換

置換とは文字列中の特定の文字に対して、別の文字列に置き換えることを指します。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

Q&A

解決済

1回答

10337閲覧

perlでの全角文字の置換

Koh_

総合スコア27

Perl

Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

置換

置換とは文字列中の特定の文字に対して、別の文字列に置き換えることを指します。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

0グッド

0クリップ

投稿2017/12/03 08:01

当方perl 初心者です。
perlでファイルを読み込んで文字列を置換しようと試みましたが,うまくいきませんでした。
どなたかご教授ください,

やりたいこと
test.txtにある「¥○○○」の数字の羅列の「¥」(全角)を削除したい。

問題
decodeが正しく使えていないのか,「¥」の置換ができない。
なお,スクリプトはutf8で保存している。

teratail2.pl

perl

1use strict; 2use warnings; 3use utf8; 4use Encode; 5 6&kaikei("test"); 7 8sub kaikei{ 9my $filename = $_[0]; 10open (FILE_in ,"<","$filename.txt"); 11 12my $str = decode("utf-8","¥"); 13 14while(my $line = <FILE_in>){ 15 chomp($line); 16 $line=~ s/$str//; 17 print "$line\n"; 18 } 19}

test.txt

text

1¥1000 2¥10056 3¥946 4¥10500 5¥5460 6¥168860 7¥165 8¥1000 9

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

perlにおいていわゆる全角文字を含む多国語文字列を扱う場合は、すべての対象文字列を「内部コード」に変換して行うのが鉄則です。これの実態は特殊なUTF8コードなのですが、そんなことはどうでもよくて、とにかく「内部コード」というものが重要だと考えてください。

取り込んだ文字列は可及的速やかに内部コード化すること。文字列をコピーしたり一部分切り取ったり置換したりという処理はすべて「内部コード」化した文字列について行うこと。出力する寸前にシフトjisなりutf8なりに変換すること。回りくどく思えても一切例外を作ってはいけません。

use utf8 は、ソースコード中に直接書き込まれた全角文字を「内部コード」として扱うよう宣言するものです。use utf8している以上、"¥"は既に内部コードなので、my $str = decode("utf-8","¥");は要りません。というか使ってはいけません。

ファイルからデータを読み込む際は、いくつか方法がありますが、open関数で適切なオプションを指定してやるのが簡単です。

open(FILE_in ,"<:utf8","$filename.txt");

ひとたび内部コード化されたら、その処理は半角数字やアルファベットを使う時と全く同じに実行してかまいません。

また、内部コード化された文字列を出力する際、そのままprintで出力しようとするとエラーが起こります。ファイルに出力するなら、出力先は次のような感じでopenします。

open(FOUT, ">:utf8", "out.txt");

標準入出力に対してはbinmodeで指定できます。

binmode STDIN, ':utf8'; binmode STDOUT, ':utf8';

シフトjisを使いたいなら次のようになります。

binmode STDIN, ':encoding(cp932)'; binmode STDOUT, ':encoding(cp932)';

注意点はざっとこんな感じです。この基本を押さえ、これ以外の余計なコード変換をしようとか考えないことが重要です。

投稿2017/12/03 08:26

KojiDoi

総合スコア13692

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Koh_

2017/12/03 08:57

内部コードとして処理するんですね。 ずっと悩んでいた文字コード周りの理解がスッキリしました。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問