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

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

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

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

Q&A

解決済

2回答

4051閲覧

perlを使用substrで文字化け

spim

総合スコア16

Perl

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

0グッド

1クリップ

投稿2018/04/18 06:20

編集2018/04/19 01:58

shiftjisで書かれたperlのプログラムで、
substrで文字を分割したところ、
分割した文字が化けてしまいます。

あいうえおかきくけこと入力すると、
$leftname =・
$rightname =ア
と文字化けしてしまいます。

local($s,$p,$l) = @_;
$s =~ s/(.)/$1\0/g;
$s =~ s/([\x81-\x9f\xe0-\xfc])\0(.)\0/$1$2\0\0/g;
$s = $l eq '' ? substr($s,$p2):substr($s,$p2,$l*2);
$s =~ tr/\0//d;
$s;
こちらを入れると文字化けが対応できるとのことですが、
文字化けの解消がされませんでした。

こちらの対処方法をご教示いただければと存じます。
宜しくお願いいたします。

試したコードは下記の通りです。

sub z_substr { local($s,$p,$l) = @_; $s =~ s/(.)/$1\0/g; $s =~ s/([\x81-\x9f\xe0-\xfc])\0(.)\0/$1$2\0\0 /g; $s = $l eq '' ? substr($s,$p*2):substr($s,$p*2,$l*2); $s =~ tr/\0//d; $s; } sub bunkatsu { my $str = $name; my $length = length $str; if ($length =10) { $leftname = &z_substr($str, 0, 5); $rightname = &z_substr($str, length($str) - 5, 5); } }

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

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

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

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

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

guest

回答2

0

ベストアンサー

せっかくdecodeしたものをわざわざencodeし戻したうえで処理しようとしているのがおかしいです。

perlで日本語文字列を処理(検索・分割・結合などすべて)したい場合は、かならずdecodeした文字列に対して行ってください。encodeを行うのは、最後にコンソールやファイルに出力する直前です。これはperlでの多言語処理を行う場合の鉄則で、例外はないと思って構いません。

逆にencodeせずに文字列を出力しようとするとエラーが出て怒られます。直前にencode関数をかますか、あるいはopenかbinmodeでデフォルトの出力コードを指定してやる必要があります。

投稿2018/04/18 06:56

KojiDoi

総合スコア13671

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

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

spim

2018/04/18 07:36

KojiDoi様 ご回答ありがとうございました。 エンコードのみとしたところ、文字化けが酷く、 エンコードの箇所を削除したところ、 古河新太郎と入力すると、 分割した結果が、 左:古河・ 右:V太郎 と、分割するところの箇所のみ文字化けが発生しております。 こちらを解消する方法はございますでしょうか? 宜しくお願い申し上げます。
KojiDoi

2018/04/18 09:31

>エンコードのみとしたところ ですから、 やるべき事はデコードです。デコードするべき所でしなかったりエンコードするべき所でしなかったりすればうまく行かないのは当然です。 もう一度良います。処理はデコード済みのデータに対して行ないます。出力する直前にデータのエンコードを行ないます。 これらを省略してはいけません。 これ以外のタイミングでデコード/エンコードを試みてもいけません。 なんとなくの発想で試行錯誤しても泥沼に嵌まるだけです。鉄則を押さえてください。
spim

2018/04/19 01:40

KojiDoi様 お世話になっております。ご回答ありがとうございました。 shiftjisを使っていると同様のエラーが発生するようで、 文字列の置換というのに変更いたしましたが反映されません。 原因は何が考えられるのでしょうか? 宜しくお願いいたします。
KojiDoi

2018/04/19 03:47

同じことを何度書けばいいのでしょうか。でコードしてください。デコードしない文字列に対して置換やその他の処理を加えてはいけません。
KojiDoi

2018/04/19 03:50

それから関数内のs///は意味不明です。何をどうしたかったのでしょうか?
spim

2018/05/07 01:07

KojiDoi様 お世話になっております。エンコードとデコードを適切な場所で行ったところ、 文字化けは解消されました。色々とありがとうございました。
guest

0

文字列は文字の連なりで、文字はコンピュータでは文字コードで扱います。
今のところそこまでの知識で十分だと思います。

以下のようにしてみましたが、どうでしょうか?

perl

1# シフトJISでファイル保存する必要があります 2# コンソールの出力もシフトJISに対応している必要があります 3 4bunkatsu('あいうえおかきくけこ', 5); 5print 'leftname=', $leftname, "\n"; 6print 'rightname=', $rightname, "\n"; 7 8bunkatsu('古河新太郎', 2); 9print 'leftname=', $leftname, "\n"; 10print 'rightname=', $rightname, "\n"; 11 12sub bunkatsu { 13 my($str, $leftchar) = @_; 14 $leftname = substr($str, 0, $leftchar * 2); 15 $rightname = substr($str, $leftchar * 2); 16} 17__END__

投稿2018/04/30 15:28

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

KojiDoi

2018/05/01 10:38

これではダメです。文字列にいわゆる半角文字が混じれば破綻します。未来永劫いわゆる全角文字のみからなる文字列しか受け付けないという仮定があるならともかく、多くの場合現実的ではありません。 perlで多バイト文字列の処理を試みるなら、デコード→処理→エンコードが唯一確実な手順なのです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問