• ベストアンサー

Perlでの文字列操作について

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

質問者が選んだベストアンサー

  • ベストアンサー
  • kumoz
  • ベストアンサー率64% (120/185)
回答No.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] に変更するやり方がありますが、数字列に . や - が含まれる場合は分割 されることになります。

その他の回答 (4)

  • steel_gray
  • ベストアンサー率66% (1052/1578)
回答No.4

#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

  • kumoz
  • ベストアンサー率64% (120/185)
回答No.3

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

ken6791
質問者

補足

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

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

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

  • steel_gray
  • ベストアンサー率66% (1052/1578)
回答No.1

以下のサンプルが参考になれば幸いです。 (想定外のデータを処理すると無限ループになるのでこのままではやや危険。) $str = '11A4C555D67B114B9423C'; #解析対象 while($str){ # ループ $strの内容が空になるまで。 $str =~ s/\d+\D+//; # 数字とそれに続く数字以外を''に置換 push @arr,$&; # マッチした部分を配列に格納 } #以下は確認用 foreach(@arr){ print $_,"\n"; } ↓結果 11A 4C 555D 67B 114B 9423C

ken6791
質問者

補足

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

関連するQ&A