- ベストアンサー
文字列の分割について
VB初心者です。 以下のように文字列を分割したいのですが <やりたいこと> MOJI="A","B","C,D,E" ↓ ARRAY(0)="A" ARRAY(1)="B" ARRAY(2)="C,D,E" ARRAY=SPLIT(MOJI,",") ではだめですよね。 何か、簡単なやり方はありますか? よろしくお願いします。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
大概の場合はうまくいくと思います。 Function csv(source) As Variant Dim reg As New RegExp Dim mc As MatchCollection Dim buf Dim i Dim bobj As Object Dim arry() If Len(source) > 0 And Left(source, 1) <> "," Then buf = buf & "," Else csv = "" Exit Function End If reg.Pattern = "(""[^""]*""),|([^""]*)," reg.Global = True Set mc = reg.Execute(source) If mc.Count <> 0 Then reg.Pattern = ",$" ReDim arry(mc.Count) For i = 0 To mc.Count - 1 arry(i) = reg.Replace(mc(i), "") Next End If csv = arry End Function
その他の回答 (4)
- MARU4812
- ベストアンサー率43% (196/452)
補足の説明が。。。回答者の意図を分かってないですね。 VB6で > MOJI="A","B","C,D,E" は文法エラーです。この時点でVB6の文法で文字列を 理解していない事になります。ダブルクォーテーションは 文法として意味を持ちます。 データのダブルクォーテーションと、VB6の文法の ダブルクォーテーションを区別して説明して下さい。 「CSV形式でデータの中にカンマを含む場合」でいいですか? VB6の文法としてそのようなデータを変数に入れるなら、 MOJI = """A"",""B"",""C,D,E""" となります。 変数、MOJI に「"A","B","C,D,E"」というデータを入れる という意味です。ダブルクォーテーションが文法としての 意味を持っているため、2つ重ねてエスケープします。 ここで、CSV形式は「データ中にカンマを含まない場合」 はダブルクォーテーションで囲まないでも成り立つ事が 重要です。 CSV形式のデータを正しく読み取るには、データとして 「A,B,"C,D,E"」も「A」「B」「C,D,E」と解釈できる 必要があります。更に「データ中にダブルクォーテーション を含む場合」も許可されています。「A,B,"C,""D,E"」は 「A」「B」「C,"D,E」と解釈します。 http://www.kasai.fm/wiki/rfc4180jp 理解した上で説明しなおしてください。
- layy
- ベストアンサー率23% (292/1222)
配列に入れて添え字何個か数える?。 プログラミング的にいうと区切りを数える、でも解決します。 『","』の出現数=2 1バイトずつ見て、2バイト前、1バイト前とともに判定する。 配列ARRAYの知識いりません。
- nda23
- ベストアンサー率54% (777/1415)
簡単なやり方はありません。 憶えておくと便利な正規表現を使います。 【理論】 (1)引用符で囲まれた部分を配列に記録 (2)引用符で囲まれた部分を非表示文字で置換 (3)カンマで分割 (4)分割した内容に置換文字があれば 配列に記録した元の文字列で復元 【プログラム例】 Function 分割(ByVal MOJI) Dim 編集後文字列 Dim 正規表現 Dim 一致集合 Dim 要素 Dim 添字 Dim 分割配列 ReDim 引用符内部(0) '正規表現オブジェクトをインスタンス化する Set 正規表現 = CreateObject("VBScript.RegExp") '置換対象を「全て」にする 正規表現.Global = True '引用符で囲まれた文字列を示す正規表現パターン 正規表現.Pattern = """.*?""" '上記に一致する集合を得る Set 一致集合 = 正規表現.Execute(MOJI) '引用符で囲まれた部分を記録する配列の要素数を初期化 添字 = -1 '一致集合から一つずつ取り出して配列に記録する For Each 要素 In 一致集合 '要素数をインクリメントする 添字 = 添字 + 1 '配列の要素数を以前の内容を残して拡張する ReDim Preserve 引用符内部(添字) '拡張した要素に記録 引用符内部(添字) = 要素 Next '引用符で囲まれた部分をBackSpaceで置換する 編集後文字列 = 正規表現.Replace(MOJI, vbBack) 'カンマで区切る 分割配列 = Split(編集後文字列, ",") '検出/置換の範囲を「最初だけ」にする 正規表現.Global = False 'BackSpaceの正規表現パターン 正規表現.Pattern = "\x08" '復元用添字を初期化する 添字 = -1 '分割した配列を一つずつ処理する For 要素 = 0 To UBound(分割配列) 'データにBackSpaceが含まれる限りループする Do While 正規表現.Test(分割配列(要素)) '復元用添字をインクリメントする 添字 = 添字 + 1 'BackSpaceを復元する 分割配列(要素) = _ 正規表現.Replace(分割配列(要素), _ 引用符内部(添字)) Loop Next '戻り値として配列を返す 分割 = 分割配列 End Function 【実行例】 Dim MOJI, 結果, 要素 MOJI = """A"",""B"",""C,D,E""" 結果 = 分割(MOJI) Debug.Print MOJI For Each 要素 In 結果 Debug.Print 要素 Next 尚、引用符内に引用符を置く可能性がある場合は 先にその部分(二重引用符とかエスケープ指定)を 置換しておいてから同じ操作を行います。 正規表現は以下を参照してください。 http://msdn.microsoft.com/ja-jp/library/cc392487.aspx
お礼
ありがとうございます。 試してみます。
- imogasi
- ベストアンサー率27% (4737/17069)
簡単なコード(split関数)ではむつかしいですね。レベル(優先度)をつけて一遍には出来ないでしょう。 Instr関数で文字の出現位置を順次探り、抽選順位を判別ロジックで組まないといけないように思う。 しかし当初の文字列の内容があいまいなので下記補足を乞う。 ーーー >VB初心者です VBA、VB6,VB.NETのうちのどれですか? >MOJI="A","B","C,D,E" これをそのままコード(代入文)として載せるとエラーになると思う。 実際に動く、プログラムの代入文の表現ではどうなりますか?内容を正確に知りたいため。 分割単位の意味が不明のところが出るようにおもう。 代入する特はARRAY(0)="A"でも、Msgbox で表示すると A であり、本当はAと表示したいのか、”A"と表示したいのか 質問では紛らわしいから。 ーーー Arrayという変数は、別にArray関数というのがあり、紛らわしいので避けるべきでしょう。 -- 単なる思い付きで疑問に思った例ですか? 実際に実務などしていて、ぶつかった例ならもう少し詳しく、直面したケースを広く教えてください。
補足
回答ありがとうございます。 細くしますと VB6 で、例がよくなかったですね。 MOJI="A","B","C,D,E" ↓ TempAry(0) = "A" "A"の文字列として扱いたい。 TempAry(1) = "B" TempAry(2) = "C,D,E" で分割した配列の個数を知りたいのですが? たとえば、 MOJI="A","B","C" ↓ TempAry=Aplit(MOJI,",") UBOUND(TempAry) → 2ですよね、上記も同様のことがしたいのですが? すいません、簡単に書きすぎました。 よろしお願いします。
お礼
ありがとうございます。 試してみます。