人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

ああ,いいA,ううB,ええC,おおC,かかA、さくら,ももA,りんごB,ぶどうC

というデータがあるとします。

これを「さくら」から後ろのデータ毎に整理したいです。
「さくら」の後にはなにもアルファベットが付いていないので、「ああ」が対応します。
「もも」はAで終わっているので、「いい」と「かか」が対応します。
「りんご」はBで終わっているので、「うう」が対応します。
各アルファベットは削除して取り出したいです。
結果下のようになります。

さくら、ああ
もも、いい、かか
りんご、うう
ぶどう、ええ、おお

このようなデータにするためにperlで書く正規表現のヒントをください。
そのものずばりでなくてもヒントでもOKです。

どうぞよろしくお願いいたします。


●質問者: cazzac
●カテゴリ:コンピュータ ウェブ制作
✍キーワード:Perl さくら ぶどう りんご アルファベット
○ 状態 :終了
└ 回答数 : 3/3件

▽最新の回答へ

1 ● t_shiono
●27ポイント

前半の名前の部分にアルファベットを含むものが来ないという条件でですが、以下の手順で十分ではないでしょうか?

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);
?>

何かの参考になれば。

◎質問者からの返答

参考にさせていただきます。

ありがとうございました。


2 ● kn1967
●27ポイント

正規表現ではなくて文字コードのほうが問題になるかと思うのですが・・・。

それはさておきメモ帳でコードを作成して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;

としてもエラーが出てしまいます。

もしお答えいただけましたら幸いです。どうぞよろしくお願いいたします。


3 ● kn1967
●26ポイント

$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,ぶどう,ええ,おお
関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ