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


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

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

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

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

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

回答の条件
  • 1人3回まで
  • 登録:2008/10/06 00:46:11
  • 終了:2008/10/13 00:50:03

回答(3件)

id:t_shiono No.1

t_shiono回答回数256ベストアンサー獲得回数222008/10/06 04:21:32

ポイント27pt

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

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

何かの参考になれば。

id:cazzac

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

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

2008/10/07 23:55:39
id:kn1967 No.2

kn1967回答回数2915ベストアンサー獲得回数3012008/10/06 04:22:35

ポイント27pt

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

それはさておきメモ帳でコードを作成して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,ぶどう,ええ,おお
id:cazzac

実行までしていただきましてありがとうございました。

勉強しなおします。

すいません。perl初心者でして、先日からいろいろやっているのですが、追加の質問があります。

$a =~ s/(.+)、(.+)/$2,$1/;

は、”、”前後を入れ替える処理をしていると思いますが、$2,$1にそれぞれ何が入っているか見る方法はありますでしょうか?

print $2;

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

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

2008/10/08 20:03:18
id:kn1967 No.3

kn1967回答回数2915ベストアンサー獲得回数3012008/10/10 00:13:21

ポイント26pt

$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,ぶどう,ええ,おお
  • id:cazzac
    kn1967さん

    お返事遅れてごめんなさい。
    わかりやすく丁寧に解説していただきましてありがとうございました。
    助かりました。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません