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

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

ただいまの
回答率

90.75%

  • Perl

    441questions

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

perlを使用substrで文字化け

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 255

spim

score 10

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,$p*2):substr($s,$p*2,$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);
  }
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

0

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

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/04/18 16:36

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

    宜しくお願い申し上げます。

    キャンセル

  • 2018/04/18 18:31

    >エンコードのみとしたところ
    ですから、 やるべき事はデコードです。デコードするべき所でしなかったりエンコードするべき所でしなかったりすればうまく行かないのは当然です。

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

    キャンセル

  • 2018/04/19 10:40

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

    キャンセル

  • 2018/04/19 12:47

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

    キャンセル

  • 2018/04/19 12:50

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

    キャンセル

  • 2018/05/07 10:07

    KojiDoi様

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

    キャンセル

0

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

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

# シフトJISでファイル保存する必要があります
# コンソールの出力もシフトJISに対応している必要があります

bunkatsu('あいうえおかきくけこ', 5);
print 'leftname=',  $leftname,  "\n";
print 'rightname=', $rightname, "\n";

bunkatsu('古河新太郎', 2);
print 'leftname=',  $leftname,  "\n";
print 'rightname=', $rightname, "\n";

sub bunkatsu {
    my($str, $leftchar) = @_;
    $leftname  = substr($str, 0, $leftchar * 2);
    $rightname = substr($str, $leftchar * 2);
}
__END__

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/01 19:38

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

    キャンセル

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

  • ただいまの回答率 90.75%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 解決済

    perl バイオインフォマティクス

    実現させたいこと ダウンロードしたmultifastaを一行ずつのものに分割し、NGSによるreadのようなものを作成したい。 先日同じような質問をさせて頂きましたが、今回もそ

  • 解決済

    GETパラメタでhtmlファイル名を渡したい。

    GETパラメタでhtmlファイル名を渡したいです。 outputExcel(category,manageNo)のcategoryにoutputFile()で開くhtmlファイル

  • 解決済

    js 文章の単語の最初を大文字に他は小文字にするには?

    実現したいこと JavaScriptで、 文章の単語の最初を大文字に他は小文字にしたいです。 例 "I'm a little tea pot" →  "I'm A Li

  • 解決済

    perlの基本操作:split関数

    前提・実現したいこと 大変恐縮ではございますがお答えいただけると幸いです。 perlの基本操作を練習中です。 split関数がうまく使えないので質問しました。 具体的には2種類の種

  • 解決済

    perlスクリプトの不具合

    いつもお世話になっております。自身で書いたperlスクリプトが思うように動かずに困っています。どなたか御教授頂けたら幸いです。 入力ファイルについて ・ file.fa >1-

  • 解決済

    perlの正規表現、サブルーチンについて

    perlの正規表現、サブルーチンについてです。 やりたいことはサブルーチンに渡された引数が "数字x数字y数字z"(数字は最大3桁) という形式だった時に計算をして値を返し、それ以

  • 解決済

    perlで変数に代入せず置換する方法

    出てきた値を置換して別の変数に入れたいです。 自分の知ってる限りだと、一度変数に収めてからs演算子で置換する方法しかわからないです。 @list=(qw/str1X str2/

  • 解決済

    CODE(....)という出力で返ってくることの対処法

    よろしくお願いいたします。   open(IN, "file.txt"); ..... $hensu = sub { if

同じタグがついた質問を見る

  • Perl

    441questions

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