というデータがあるとします。
これを「さくら」から後ろのデータ毎に整理したいです。
「さくら」の後にはなにもアルファベットが付いていないので、「ああ」が対応します。
「もも」はAで終わっているので、「いい」と「かか」が対応します。
「りんご」はBで終わっているので、「うう」が対応します。
各アルファベットは削除して取り出したいです。
結果下のようになります。
さくら、ああ
もも、いい、かか
りんご、うう
ぶどう、ええ、おお
このようなデータにするためにperlで書く正規表現のヒントをください。
そのものずばりでなくてもヒントでもOKです。
どうぞよろしくお願いいたします。
前半の名前の部分にアルファベットを含むものが来ないという条件でですが、以下の手順で十分ではないでしょうか?
1.「,」で要素を区切る。
2.各要素について、以下を繰り返す
3.アルファベットで終わるかどうかを正規表現で確認
4.3でマッチした場合には、そのアルファベットのデータとして登録
5.3でマッチしなかった場合には、アルファベット無しのデータとして登録
手元ですぐにPerlを動作確認できる環境がなかったので、PHPのコードになりますが、次のような感じで動作すると思います。
<?php function insert_result(&$result, $name, $type) { if (!is_array($result[$type])) { $result[$type] = array(); } $result[$type][] = $name; } $line = 'ああ,いいA,ううB,ええC,おおC,かかA,さくら,ももA,りんごB,ぶどうC'; $elements = explode(',', $line); foreach ($elements as $element) { if (preg_match('/(.*)([A-Z])$/', $element, $matches)) { insert_result($result, $matches[1], $matches[2]); } else { insert_result($result, $element, ''); } } print_r ($result); ?>
何かの参考になれば。
正規表現ではなくて文字コードのほうが問題になるかと思うのですが・・・。
それはさておきメモ帳でコードを作成してWindows版perl上で実行してみましたが参考になりますでしょうか?
# データ準備 $a = 'ああ,いいA,ううB,ええC,おおC,かかA、さくら,ももA,りんごB,ぶどうC'; # データ整理(、以降を最初に処理させるために先頭に持ってきてから配列化) $a =~ s/(.+)、(.+)/$2,$1/; @a = split(',', $a); # ハッシュへ代入(アルファベットが無いものはスペース) %b; foreach(@a) { if(/(.+)([A-Z])$/) { $b{"$2"} = join(',', $b{"$2"}, $1); } else { $b{" "} = join(',', $b{" "}, $_); } } # # 結果出力(アルファベット順にソート) foreach(sort keys %b) { print "$_$b{\"$_\"}\n"; }
実行結果
,さくら,ああ A,もも,いい,かか B,りんご,うう C,ぶどう,ええ,おお
実行までしていただきましてありがとうございました。
勉強しなおします。
すいません。perl初心者でして、先日からいろいろやっているのですが、追加の質問があります。
$a =~ s/(.+)、(.+)/$2,$1/;
は、”、”前後を入れ替える処理をしていると思いますが、$2,$1にそれぞれ何が入っているか見る方法はありますでしょうか?
print $2;
としてもエラーが出てしまいます。
もしお答えいただけましたら幸いです。どうぞよろしくお願いいたします。
$1や$2はマッチングを伴う処理を行う度に内容が変わっていきますので
必用であれば取得した直後に使うようにしてみてください。
$a =~ s/(.+)、(.+)/$2,$1/; print "1:$1\n"; print "2:$2\n"; print "3:$a\n"; @a = split(',', $a);
デバッグ中に、変数の内容を中途で表示させる事はよくありますが
その際にはどの位置でプリントアウトさせたのかを示すため
マーカー(今回は行の先頭に1:や2:をつけてます)をつけると良いかと思います。
# データ準備 $a = 'ああ,いいA,ううB,ええC,おおC,かかA、さくら,ももA,りんごB,ぶどうC'; # データ整理(、以降を先頭に持ってくる) $a =~ s/(.+)、(.+)/$2,$1/; print "1:$1\n"; print "2:$2\n"; print "3:$a\n"; @a = split(',', $a); # ハッシュへ代入 %b; foreach(@a) { if(/(.+)([A-Z])$/) { $b{"$2"} = join(',', $b{"$2"}, $1); } else { $b{" "} = join(',', $b{" "}, $_); } } # # 出力 print "-----結果-----\n"; foreach(sort keys %b) { print "$_$b{\"$_\"}\n"; }
出力結果
1:ああ,いいA,ううB,ええC,おおC,かかA 2:さくら,ももA,りんごB,ぶどうC 3:さくら,ももA,りんごB,ぶどうC,ああ,いいA,ううB,ええC,おおC,かかA -----結果----- ,さくら,ああ A,もも,いい,かか B,りんご,うう C,ぶどう,ええ,おお
参考にさせていただきます。
ありがとうございました。