電子書籍の厳選無料作品が豊富!

Perlを使用しての文字列操作について教えてください。
たとえば以下のような数字とアルファベットが順に並ぶ文字列があるとします。
11A4C555D67B114B9423C
アルファベットは1文字ですが、数字は何個でも連続で並びます。
この文字列を「数字アルファベット」の部分で分割し、配列に格納したいのですが、うまくいきません。
@array=('11A','4C','555D','67B','114B','9423C')
どなたか教えてください。よろしくお願いいたします。

A 回答 (5件)

> splitの中で、(?<=[A-Z])(?=\d)|(?<=\d)(?=[A-Z]) は何をしているのでしょうか?



この正規表現によって、位置を指定しています。位置は、文字と文字の間にあると考えてください。
(?<=[A-Z]) は位置の前の文字がアルファベットの大文字であることを要求し、(?=\d) は位置の次の
文字が数字であることを要求します。また、選択肢の次の正規表現は逆に並んでいることを要求し
ます。結局は、アルファベットの大文字と数字が隣接している位置で文字列は分割されることにな
ります。

> あと、たとえば特殊記号が文字列の中に入っていた場合とかどうでしょうか?
> 11A4C555ED6GFS7~BN → 11 A 4 C 555 ED 6 GFS 7 ~BN
> 例えば、特殊文字(今は「~」)がアルファベットの直前に来ていて
> それはアルファベットと付けて格納。

特殊文字の数が少なければ [A-Z] を [A-Z~] のように、文字クラスの中に追加するのが簡単です。
また、[A-Z] を [^\d] に変更するやり方がありますが、数字列に . や - が含まれる場合は分割
されることになります。
    • good
    • 0

#1です。

#3で補足の回答も含まれてますが一応。

$str = '11A4C555D67B114B9423C'; # 解析対象
@arr = $str =~ m/(\d+\D+)/g; #2さんの方法がスマートだったので変更

#以下は確認用
foreach(@arr){
($decimal,$alpha) = m/(\d+)(.*)/; # 数値とそれ以降に分離
print $decimal.'::'.$alpha,"\n"
}

↓結果
11::A
4::C
555::D
67::B
114::B
9423::C
    • good
    • 0

split 関数の正規表現に位置を表す空文字を指定するのも1方法かと思います。



@array = split /(?<=[A-Z])(?=\d)/, '11A4C555D67B114B9423C'; # 11A, 4C, 555D, 67B, 114B, 9423C
@array = split /(?<=[A-Z])(?=\d)|(?<=\d)(?=[A-Z])/, '11A4C555D67B114B9423C'; # 11, A, 4, C, 555, D, 67, B, 114, B, 9423, C

この回答への補足

回答ありがとうございました。
kumozさんのやり方でお伺いしたいのですが、
splitの中で、(?<=[A-Z])(?=\d)|(?<=\d)(?=[A-Z])
は何をしているのでしょうか?
詳しく教えていただけないでしょうか?
あと、たとえば特殊記号が文字列の中に入っていた場合とかどうでしょうか?
11A4C555ED6GFS7~BN → 11 A 4 C 555 ED 6 GFS 7 ~BN
例えば、特殊文字(今は「~」)がアルファベットの直前に来ていて
それはアルファベットと付けて格納。

何度も申し訳ございませんが、よろしくお願いいたします。

補足日時:2010/03/23 02:00
    • good
    • 0

配列コンテキストで /(\d+[a-zA-Z])/g;

    • good
    • 0

以下のサンプルが参考になれば幸いです。


(想定外のデータを処理すると無限ループになるのでこのままではやや危険。)

$str = '11A4C555D67B114B9423C'; #解析対象
while($str){ # ループ $strの内容が空になるまで。
$str =~ s/\d+\D+//; # 数字とそれに続く数字以外を''に置換
push @arr,$&; # マッチした部分を配列に格納
}
#以下は確認用
foreach(@arr){
print $_,"\n";
}

↓結果
11A
4C
555D
67B
114B
9423C

この回答への補足

早速の回答ありがとうございました。
うまくできました。
もうひとつ質問をしてもいいでしょうか?
分解した結果を、数字と英数字に再度分解するためにはどうすればいいでしょうか?
11A が 11とA に、
4C が 4とCに
よろしくお願いいたします。

補足日時:2010/03/22 02:29
    • good
    • 0

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