許せない心理テスト

perlで文字・数字の置換又は抽出に関する質問です。

print $line,"\n";
で文字を出力すると
29日(日)
30日(月)
1日(火)
2日(水)
・・・

のように出力できています。
これを以下のように出力したいと思っています。

1日目文字列:29日(日)
1日目日付:29
1日目曜日:日
2日目文字列:30日(月)
2日目日付:30
2日目曜日:月
3日目文字列:1日(火)
3日目日付:1
3日目曜日:火
・・・

日付のみの抽出、曜日のみの抽出はどのようにすればいいでしょうか。
教えてください。よろしくお願いします。

質問者からの補足コメント

  • つらい・・・

    No.5とNo.6のお礼に記載してあるプログラムの最下部に下のプログラムを実行したところ
    --------------------------------
    $line = ~ /(\d+)日\((.+)\)/;

    print $1,"\n";
    print $2,"\n";
    --------------------------------
    この追加したラインに
    use of uninitialized value $_ in pattern match (m//) at …
    use of uninitialized value $1 in print at …
    use of uninitialized value $2 in print at …
    のエラーが出ています。どうしたらいいのでしょうか。ご教示ください。

    No.9の回答に寄せられた補足コメントです。 補足日時:2017/08/21 00:02

A 回答 (10件)

> Malformed utf-8 character (unexpected continuation byte…



上記のメッセージは、ソースファイルが cp932 (or Shift_JIS) で書かれていて、use utf8; 宣言されているときに出ます。ソースファイルを UTF-8 に変更する必要があります。
    • good
    • 0
この回答へのお礼

ありがとうございます。
今度はNo.5とNo.6のお礼に記載してあるプログラムの最下部に下のプログラムを実行したところ
--------------------------------
$line = ~ /(\d+)日\((.+)\)/;

print $1,"\n";
print $2,"\n";
--------------------------------
この追加したラインに
use of uninitialized value $_ in pattern match (m//) at …
use of uninitialized value $1 in print at …
use of uninitialized value $2 in print at …
のエラーが出ています。どうしたらいいのでしょうか。ご教示ください。

お礼日時:2017/08/27 16:48

> while(my $line = decode('cp932', $fh->getline())){



$line =~ /正規表現/;

while の条件文から、$line は UTF-8 の内部文字列なので、正規表現も UTF-8 の内部文字列である必要があります。正規表現の文字コードは、No.5, 6 のお礼には書かれていない部分に依存します。文字コードがどうなっているのか、確認してみてください。

* ソースファイルの文字コードは UTF-8 になっているか?
* Encode, utf8 モジュールは指定されているか?
* open, binmode 等の関数の使用状況は?
この回答への補足あり
    • good
    • 0
この回答へのお礼

ありがとうございます。
$line =~ /正規表現/; を足してやると
Malformed utf-8 character (unexpected continuation byte…
といったエラーが出ています。「rararaxx」さんの言うとおり、UTF-8としての文字解釈が出来ないようです。
最初に以下のようにモジュールを指定しているのですが、これだけでは不足でしょうか?すいませんが、お教えください。
use Encode;
use utf8;
binmode STDOUT => ":encoding(cp932)";

お礼日時:2017/08/20 22:45

'29日(日)' というデータから '29' と '日' を取り出すというのであれば, 既に #2 や #3 で書かれている通りの方法を使うのが普通でしょう.



「エラーが出た」といっても
・どのようなデータに対して
・どのようなプログラムで
・どのようなエラーが出たのか
がまったくわからないままですが.
    • good
    • 0
この回答へのお礼

$line =~ /(\d+)日\((.+)\)/;

print $1,"\n";
print $2,"\n";

コードの末尾に「めぐみん_」さんからの頂いたコードを貼り付けて実行すると
この貼り付けたコードに対して以下のようなエラーコードが出ています。
Malformed utf-8 character (unexpected continuation byte…

UTF-8としての文字解釈が出来ないようですが、どうしたらいいでしょうか。

お礼日時:2017/08/20 22:38

たぶん同案多数だと思うんだけど....



そのプログラムでなにをしたいんですか? 「プログラム全体としてなにをしたいのか」「その部分でなにをしている (つもりな) のか」がわからないです.

そしてもともとの質問文との関連もわからない.
    • good
    • 0
この回答へのお礼

うーん・・・

すいません。
以下のようなtest.csvの記事から日付と曜日部分のみ取り出すプログラムを書きたいと思っています。
------------------------
戦績
29日(日)
勝ち
30日(月)
勝ち
1日(火)
負け
2日(水)
勝ち
・・・
------------------------
print $line, "\n";で「●日目文字列」の表示は出来るようになったので、この中から今度は日付と曜日を抜き出そうと思っています。本当の最終的な理想形は以下のように自在に出力したいと思っています。
print "1日目文字列:", $Game{syuukan}{'1日目文字列'}, "\n"; #29日(日)
print "1日目日付:", $Game{syuukan}{'1日目日付'}, "\n"; #29
print "1日目曜日:", $Game{syuukan}{'1日目曜日'}, "\n"; #日

自分の知識不足です。わかりにくい質問で申し訳ありませんが助けてください。お願いします。

お礼日時:2017/08/12 00:52

あなたから出てきている情報が少なすぎるので「何が問題なのか」はわかりません. さしあたり


・Perl で書いたプログラム全体
・問題が発生するデータを数行
・perl が出しているエラーメッセージ全部
・プログラムとデータの文字コード
・perl のバージョン
を出してもらえますか?
    • good
    • 0
この回答へのお礼

my $Syu = File::Spec->catfile($basedir, 'DATA', 'test.csv');

our %Game;
our %Week = (
'2' => '1日目文字列',
'4' => '2日目文字列',
'6' => '3日目文字列',
'8' => '4日目文字列',
'10' => '5日目文字列',
);

my @in;
foreach my $key (keys %Week){
$in[$key] = $Week{$key};
}
my $fh = IO::File->new("<" . encode('cp932', $Syu)) or die "Can not open " . $Syu . ":" . $!;

while(my $line = decode('cp932', $fh->getline())){
my $line_no = $fh->input_line_number;
next unless $in[$line_no];
chomp($line);
unless(ref $Week{$line_no}){
$Game{syuukan}{$Week{$line_no}} = $line;
print $line, "\n";

}
}

これ以降どうやったらいいのでしょうか?お願いします。
ちなみにperlのverはv5.14.1です。

お礼日時:2017/08/10 00:23

>print $line



この変数の中身が回答者にはまだ足りない情報が詰まっている?
これを実行する前にどのように取得しているのか?が気になってきますけど。
    • good
    • 0
この回答へのお礼

my $Syu = File::Spec->catfile($basedir, 'DATA', 'test.csv');

our %Game;
our %Week = (
'2' => '1日目文字列',
'4' => '2日目文字列',
'6' => '3日目文字列',
'8' => '4日目文字列',
'10' => '5日目文字列',
);

my @in;
foreach my $key (keys %Week){
$in[$key] = $Week{$key};
}
my $fh = IO::File->new("<" . encode('cp932', $Syu)) or die "Can not open " . $Syu . ":" . $!;

while(my $line = decode('cp932', $fh->getline())){
my $line_no = $fh->input_line_number;
next unless $in[$line_no];
chomp($line);
unless(ref $Week{$line_no}){
$Game{syuukan}{$Week{$line_no}} = $line;
print $line, "\n";

}
}

これ以降どうやったらいいのでしょうか?お願いします。
ちなみにperlのverはv5.14.1です。

お礼日時:2017/08/10 00:23

#3 のところ, 「うまく処理されない」とはどういうことでしょうか? 具体的にはどのような入力に対してどのようになっていることを「うまく処理されない」といっているのでしょうか?



漢字とか英数字とかが混ざると文字コードの問題もあり得るのですが, そこは大丈夫でしょうか?
    • good
    • 0
この回答へのお礼

以下のようなエラーが出ています。何が問題なのでしょうか。わかりましたら教えてください。
Use of uninitialized value $1 in print at …test.pl …
Use of uninitialized value $2 in print at …test.pl …

お礼日時:2017/08/08 15:01

どうも数字が全角半角混在の様なので、厳しくやるならば



my $c = 0;
foreach $line (<>) {
chomp $line;
if ($line =~ /^(.+?)日((.+?))/) {
$c++;
printf("%s日目文字列:%s\n", &h2z($c), $line);
printf("%s日目日付:%s\n", &h2z($c), &z2h($1));
printf("%s日目曜日:%s\n", &h2z($c), $2);
}
}
# 数字の全角半角変換、utf8 の tr が使えるなら不要です
sub h2z {
my $a = $_[0];
$a =~ s/0/0/g;
$a =~ s/1/1/g;
$a =~ s/2/2/g;
$a =~ s/3/3/g;
$a =~ s/4/4/g;
$a =~ s/5/5/g;
$a =~ s/6/6/g;
$a =~ s/7/7/g;
$a =~ s/8/8/g;
$a =~ s/9/9/g;
$a;
}
sub z2h {
my $a = $_[0];
$a =~ s/0/0/g;
$a =~ s/1/1/g;
$a =~ s/2/2/g;
$a =~ s/3/3/g;
$a =~ s/4/4/g;
$a =~ s/5/5/g;
$a =~ s/6/6/g;
$a =~ s/7/7/g;
$a =~ s/8/8/g;
$a =~ s/9/9/g;
$a;
}
    • good
    • 0
この回答へのお礼

一応数字は全て半角にするつもりでした。指摘ありがとうございます。
$line =~ /^(.+?)日((.+?))/
でうまく処理されないのはなんでなんでしょう。。。

お礼日時:2017/08/08 14:09

$line = "29日(日)";


$line =~ /(\d+)日\((.+)\)/;

print $1,"\n";
print $2,"\n";

29


こんな感じかな?
    • good
    • 0
この回答へのお礼

ありがとうございます。
ただ以下のようなエラーが出ています。何が問題なのでしょうか。
Use of uninitialized value $1 in print at …test.pl …
Use of uninitialized value $2 in print at …test.pl …

お礼日時:2017/08/08 14:06

m// でマッチさせるのが普通でしょうか.

    • good
    • 0
この回答へのお礼

ありがとうございます。もうちょっと勉強してみます。

お礼日時:2017/08/08 14:07

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


おすすめ情報