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

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

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

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

Q&A

解決済

1回答

2439閲覧

perlの基本操作:split関数

SoYamamoto

総合スコア10

Perl

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

0グッド

0クリップ

投稿2017/06/13 05:15

編集2017/06/13 06:19

###前提・実現したいこと
大変恐縮ではございますがお答えいただけると幸いです。
perlの基本操作を練習中です。
split関数がうまく使えないので質問しました。
具体的には2種類の種名をファイルから読み込んで分類するプログラムを実行しようとした際うまく行かず、どうやら二つの配列に要素が分割され、入力されていないのが原因のようです。
###発生している問題・エラーメッセージ

perl practice_ref_common.pl siritori_words.txt リンゴ ゴリラ ラッパ パンツ ツミキ キツネ ネズミ ミミズ キツネ ラッパ ゴリラ ランプ ズンダ ダンゴ ゴング グンテ common species only in the first group リンゴ ゴリラ ラッパ パンツ ツミキ キツネ ネズミ ミミズ キツネ ラッパ ゴリラ ランプ ズンダ ダンゴ ゴング グンテ only in the second group

###該当のソースコード

perl

1ファイル名:practice_ref_common.pl 2@species1 = (); 3@species2 = (); 4 5#ファイルから読み込み 6while ($line = <>) { 7 8 chomp $line; 9 ($sp1, $sp2) = split (/\s+/, $line); 10 print $sp1, "\n"; #ここで問題発覚 11 push @species1, $sp1; 12 push @species2, $sp2; 13} 14 15 16($ref_common, $ref_only_in1, $ref_only_in2) = &find_common(\@species1, \@species2); 17 18print "common species\n"; 19foreach $sp (@$ref_common) { 20 print $sp, "\n"; 21} 22print "\n"; 23 24print "only in the first group\n"; 25foreach $sp (@$ref_only_in1) { 26 print $sp, "\n" 27} 28 29print "\n"; 30 31print "only in the second group\n"; 32foreach $sp (@$ref_only_in2) { 33 print $sp, "\n"; 34} 35 36sub find_common 37{ 38 my ($ref1, $ref2) = @_; 39 40 my @common = (); 41 my @only_in1 = (); 42 my @only_in2 = (); 43 44 my $found; 45 46 foreach my $sp1 (@$ref1) { 47 foreach my $sp2 (@$ref2) { 48 $found = 0; 49 if ($sp1 eq $sp2) { 50 $found = 1; 51 last; 52 } 53 } 54 55 if ($found == 1) { 56 push @common, $sp1; 57 } 58 else { 59 push @only_in1, $sp1; 60 } 61 } 62 63 foreach my $sp2 (@$ref2) { 64 foreach my $sp_common (@common) { 65 $found = 0; 66 if ($sp2 eq $sp_common) { 67 $found = 1; 68 last; 69 } 70 } 71 if ($found == 0) { 72 push @only_in2, $sp2; 73 } 74 } 75 76 return (\@common, \@only_in1, \@only_in2); 77} 78 79読み込みファイル:siritori_words.txt 80リンゴ ゴリラ 81ラッパ パンツ 82ツミキ キツネ 83ネズミ ミミズ 84キツネ ラッパ 85ゴリラ ランプ 86ズンダ ダンゴ 87ゴング グンテ

###試したこと
上記の通りです。

###補足情報(言語/FW/ツール等のバージョンなど)
より詳細な情報

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

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

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

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

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

A.Ichi

2017/06/13 06:04

ファイルの読み方を見るとファイルは2個のワードで1ライン構成ですよね。
SoYamamoto

2017/06/13 06:14

修正ありがとうございます。その通りでした! テキストファイルが適切ではなかったようです。
SoYamamoto

2017/06/13 06:16

しかしながら、依然splitで分割がうまく行いえない問題が発生していますので、質問内容を訂正します。再度見ていた開けるとありがたいです。
A.Ichi

2017/06/13 06:33 編集

文字コードの問題かもしれませんので一度ファイルをasciiコード aaa bbb内容でテストしてみてください。
SoYamamoto

2017/06/13 06:40

テキストの文字を全角から半角へ変えてテストしたところうまく行きました!!
SoYamamoto

2017/06/13 06:42

回答ありがとうございます。
A.Ichi

2017/06/13 06:42

できるならperlスクリプトもファイルもUTF8に揃えられたら良いのでは。
guest

回答1

0

ベストアンサー

こんな感じで表示されましたが

perl

1perl practice_ref_common.pl siritori_words.txt 2リンゴ 3ラッパ 4ツミキ 5ネズミ 6キツネ 7ゴリラ 8ズンダ 9ゴング 10common species 11ラッパ 12キツネ 13ゴリラ 14 15only in the first group 16リンゴ 17ツミキ 18ネズミ 19ズンダ 20ゴング 21 22only in the second group 23パンツ 24ミミズ 25ランプ 26ダンゴ 27グンテ

perlには内部コードなるものが有りますので全角の文字列の場合変換されると良いです
「UTF-8バイト文字列」を「内部文字列」に変換する

perl

1use Encode 'decode'; 2# バイト文字列(外部からの入力)を内部文字列に変換($strがUTF-8の場合) 3$str = decode('UTF-8', $str);

面倒ですが出力する場合は逆にします。

perl

1use Encode 'encode'; 2# 内部文字列をUTF-8バイト文字列に変換する場合 3$str = encode('UTF-8', $str);

サンプルを添付しました。UTF8の場合

perl

1use Encode 'decode'; 2use Encode 'encode'; 3@species1 = (); 4@species2 = (); 5 6#ファイルから読み込み 7while ($line = <>) { 8 9 chomp $line; 10 $line = decode('UTF-8', $line); 11 ($sp1, $sp2) = split (/\s+/, $line); 12 13 print encode('UTF-8',$sp1), "\n"; #ここで問題発覚 14 push @species1, $sp1; 15 push @species2, $sp2; 16} 17 18 19($ref_common, $ref_only_in1, $ref_only_in2) = &find_common(\@species1, \@species2); 20 21print "common species\n"; 22foreach $sp (@$ref_common) { 23 $sp = encode('UTF-8', $sp); 24 print $sp, "\n"; 25} 26print "\n"; 27 28print "only in the first group\n"; 29foreach $sp (@$ref_only_in1) { 30 $sp = encode('UTF-8', $sp); 31 print $sp, "\n" 32} 33 34print "\n"; 35 36print "only in the second group\n"; 37foreach $sp (@$ref_only_in2) { 38 $sp = encode('UTF-8', $sp); 39 print $sp, "\n"; 40} 41 42sub find_common 43{ 44 my ($ref1, $ref2) = @_; 45 46 my @common = (); 47 my @only_in1 = (); 48 my @only_in2 = (); 49 50 my $found; 51 52 foreach my $sp1 (@$ref1) { 53 foreach my $sp2 (@$ref2) { 54 $found = 0; 55 if ($sp1 eq $sp2) { 56 $found = 1; 57 last; 58 } 59 } 60 61 if ($found == 1) { 62 push @common, $sp1; 63 } 64 else { 65 push @only_in1, $sp1; 66 } 67 } 68 69 foreach my $sp2 (@$ref2) { 70 foreach my $sp_common (@common) { 71 $found = 0; 72 if ($sp2 eq $sp_common) { 73 $found = 1; 74 last; 75 } 76 } 77 if ($found == 0) { 78 push @only_in2, $sp2; 79 } 80 } 81 82 return (\@common, \@only_in1, \@only_in2); 83}

投稿2017/06/13 06:23

編集2017/06/13 06:59
A.Ichi

総合スコア4070

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

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

SoYamamoto

2017/06/13 07:18

詳しい回答ありがとうございます。 どうやらスペースに全角を用いてしまったことが今回の原因でした。
A.Ichi

2017/06/13 07:24

良かったです。全角スペースも頭に有りましたが、ご提示のデータに無かったので文字コードの関係と勘違いしてしまいました。出力が文字化けしてないので変だなとは思っていましたが・・・
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問