• 締切済み

任意の区切り文字でsplitする方法

VBAで任意の区切り文字でsplitする方法を教えてください。 例えば 123 456 789 333 3444 66 65 22 といようなスペースあるいはタブで区切られたテキストデータがあるとします。 これを配列に格納したいのですが、 この区切りがタブ一つとか、スペース一つとか決まっていれば split関数で簡単に配列に格納することができますが、 タブかも知れないし、スペースがかも知れないし その数も未定の場合にはどうしたら良いですか? replace関数を使って、まず全てのタブをスペースに変換し その後に、複数のスペースを一つのスペースに変換し 最後にsplit関数を使うという方法しかないでしょうか? もっとスマートな方法があれば教えてください。

  • YURUE
  • お礼率18% (72/379)

みんなの回答

  • nda23
  • ベストアンサー率54% (777/1415)
回答No.6

正規表現の例 Dim 正規表現 As Object Dim 項目集合 As Object Dim 項目個別 As Object Dim 文字列 As String '★テスト用の文字列を設定 文字列 = " AAA BBB" & vbTab & "CCC PP" '★正規表現のインスタンス化 Set 正規表現 = CreateObject("VBScript.RegExp") '★プロパティの設定 正規表現.Global = True 正規表現.Pattern = "\S+" '★正規表現による項目集合の作成 Set 項目集合 = 正規表現.Execute(文字列) '★項目集合から個別項目を順次処理する For Each 項目個別 In 項目集合   '★個別項目を表示 Debug.Print 項目個別.Value Next プロパティの意味 1.Global  文字列全体を処理するかどうかを決める。  Trueにすると全文字列を処理する。  Falseにすると、最初に一致した文字列を処理して  終了する。 2.Pattern  正規表現の本文  "\S+"は「空白(タブも含む)でない1個以上の文字列」  と言う意味です。漢字の空白も含めるたい時は  "[^ \s]+"となります。後者の意味は「漢字空白、及び  空白(タブも含む)以外の1個以上の文字列」です。  これで分かるように”\S”と”\s”は反対の意味になっています。  また、"[]"は「内部の文字のいすれかに該当」ということで、  ”[]の^”は否定を示します。"+"は「1個以上」ですね。  

  • eden3616
  • ベストアンサー率65% (267/405)
回答No.5

No2です。 No4様で既に具体例が出ていますが、参照先URLの例題を多少弄って回答します。 >もう少し具体的に使い方を教えていただけないでしょうか? >示してくださったURLも見てみましたが >どう使えば良いのか分かりませんでした。 A列の1~5行目に以下のようなデータがあるとします  123 456_789  333 3444あ66  65区切り文字22  777  888文字 同じ行のB列以降に以下の結果が表示されます 正規表現で「,」へ置換後、splitで配列bufに格納しセルへ出力しています。  123  456 789  333  3444  66   65      22  777  888 なお「▼正規表現で検索」の部分は、 マッチした区切り文字列を一覧で取得するために使用したので実質は不要です。 Sub Sample2()   '準備   Dim RE, strPattern As String, i As Long, msg As String, reMatch   Dim myTarget As Range, j As Long, buf As Variant   Set RE = CreateObject("VBScript.RegExp")   'パターン指定   strPattern = "[^0-9]+"   '正規表現の設定   With RE     'パターンを設定     .Pattern = strPattern     '大文字・小文字を区別     .IgnoreCase = True     'パターンを複数にマッチさせる     .Global = True     'セルの数だけ繰り返し     For i = 1 To 5       '対象のセルを変数に格納       Set myTarget = Cells(i, "A")       '▼正規表現で置換して配列へ格納・結果出力       buf = Split(.Replace(myTarget, ","), ",")       For j = 0 To UBound(buf)         Cells(i, j + 2) = buf(j)       Next j       '▼正規表現で検索       Set reMatch = .Execute(myTarget)       For j = 0 To reMatch.Count - 1         msg = msg & i & "行目," & j + 1 & "番目:" & reMatch(j).Value & vbCrLf       Next j     Next i   End With   '結果の表示   MsgBox msg & "以上を区切り文字として認識しました" End Sub

回答No.4

こんにちは。 >replace関数を使って、……(中略) >最後にsplit関数を使うという方法しかないでしょうか? 今の話の段階では、既存の方法を使うしかないと思います。 Excelなら、QueryTable を使えるかもしれないですが、それを「スマート」という感覚の範疇に入るのか、私は分かりません。もう少し具体性のある話でないと、現実的ではありません。 >場所によって区切り文字が違っている場合で >未知の場合にはどうしたら良いですか?  どんな言語でも、厳密には、未知のものに対応出来るとは思えません。 時々ある話ですが、固定長以外にも、なんとテキストで見えていたデータの中身に、区切り信号は、バイナリでした、という話もあります。 例えば、元のデータが数字が必要なら、デリミタを統一するのではなく、正規表現で、数字を拾えばよいのではないでしょうか?そして、ここで出てきたものに、Splitを掛ければよいでしょうね。 '// Function RegPickers(myChrs As Variant) Const DELIM As String = "," Dim Matches As Object Dim Match As Object Dim buf As String With CreateObject("VBScript.RegExp")  .Pattern = "\d+"  .Global = True  Set Matches = .Execute(myChrs)  For Each Match In Matches   buf = buf & DELIM & Match  Next  RegPickers = Mid(buf, 2) End With End Function '// ある程度のデリミタが想定できるなら、\sというワイルドカードがあります。 \s = スペース、復帰コード,タブ,改行コード,ラインフィード '// Function RegSepRep(myChrs As Variant) Const DELIM As String = "," Dim Matches As Object Dim Match As Object Dim buf As String With CreateObject("VBScript.RegExp")  .Pattern = "(\w+)\s*" '\sをデリミタとする。  .Global = True  Set Matches = .Execute(myChrs)  For Each Match In Matches   buf = buf & Match.SubMatches(0) & DELIM  Next  RegSepRep = Mid(buf, 1, Len(buf) - 1) End With End Function '//

回答No.3

> 全ての場合において区切り文字が同じであればそれでも良いですが > 場所によって区切り文字が違っている場合で > 未知の場合にはどうしたら良いですか? もしかして、1つのデータの中で、場面に応じて区切り文字が違うとか言ってますか? そうだとしたら、それはそもそもインターフェースとしてNGですよね。 コロコロ区切り文字が変化する時点で、もはや区切り文字としての意義がありません。 例えばreplaceや正規表現を利用したとしても、特定データの区切り文字は半角スペースであるにも 関わらず、タブを区切り文字として認識してしまって別データとする恐れもあるので、 1つのロジックで済ますことは不可能です。 何を区切り文字とするかが分からないのに、そんな都合のいい制御できるわけありません。 可能だとしたら、区切り文字による分割ではなく、固定長文字による分割でしょう。 または、そのロジックを走行させる前に1つ1つのデータとして認識できるタイミングで 区切り文字を統一(区切り文字と認識される文字は除去)させるとか、 ダブルクォーテーションで括られている範囲内は文字列であり、区切りではないとするとか、 制約を設けないとできませんよ。

  • eden3616
  • ベストアンサー率65% (267/405)
回答No.2

正規表現で統一の区切り文字にしてあげてはどうでしょうか? 連続した数字以外は区切り文字であることが条件ですが、 123 456_789 333 3444あ66 65  22 なども、『[^0-9|\n\r]+』のような正規表現で「,」に置換してあげれば以下のようになります。 123,456,789 333,3444,66 65,22 ※ 上記パターンはテキストエディタ(sakura)で正規表現による置換をしたため改行コード(\n\r)を除外するパターン『|\n\r』が含まれていますが、セル内に改行コードが含まれないのであれば考慮にしなくても良いかと思います。 VBAでの正規表現 http://officetanaka.net/excel/vba/tips/tips38.htm http://codezine.jp/article/detail/1655

YURUE
質問者

お礼

ありがとうございます。 すいません、もう少し具体的に使い方を教えていただけないでしょうか? 示してくださったURLも見てみましたが どう使えば良いのか分かりませんでした。 よろしくお願いいたします。  

回答No.1

どういう区切り文字のインターフェースなのかをどこかのタイミングで指定させればいいだけだと思いますが。

YURUE
質問者

お礼

全ての場合において区切り文字が同じであればそれでも良いですが 場所によって区切り文字が違っている場合で 未知の場合にはどうしたら良いですか?

関連するQ&A

  • split() 正規表現

    正規表現で / (スラッシュ) .(ドット)にマッチ 正規表現により文字列を分割し、配列に格納する split("[/\.]" $v)としていましたが split関数が使えなくなるので、変わりの方法を考えていますが preg_split()などではうまくいきませんでした。 何か方法を教えて下さい。

    • ベストアンサー
    • PHP
  • splitしない文字列について

    split("\t",$moji) で$mojiを分割しているのですが、タブ区切りなのに分割しない文字列があります。 企業秘密な所もあり、問題の文字列そのままを報告できないのですが、分割をキャンセルするような文字コードってあるのでしょうか? その文字コードであやしい物は 「 」:スペース 「!」、「♪」 などが含まれています。 通常であれば10個に分割される文字列がまったく分割されなく分割数は1と出ます。もちろんタブ区切りになっています。 1つの文字列だけの事なのです。原因はまったく不明。よろしくお願いします。

    • ベストアンサー
    • PHP
  • textareaに入力されたデータを読み込む

    例えば以下のようにtextarea内にデータが入力されているとします(カンマ区切り,スペース区切り,タブ区切りなどはなんでも良いのですが)。 +---ここから---+ 1 2 3 4 5 6 7 8 9 10 11 12 +---ここまで---+ これらのデータを配列に格納する方法が,だいぶネットサーフィンしていたのですが分かりません。 以降,Perlになってしまうのですが,1行ずつ配列にdat=(1,2,3,4)のように格納していくか,あるいは行列(2次配列)の形で格納したいのです。 $pathname="D://datafile.dat"; open MYFILE, "$pathname"; while (<MYFILE>) { chomp; @{"dat$."} = split /,/; } close MYFILE; +----------- $pathname="D://datafile.dat"; open MYFILE, "$pathname"; @dat = map {chomp;[split /,/]} <MYFILE>; close MYFILE;

  • VBAで「,」⇒「.」へ置換後、タグ区切りでテキスト保存したい。

    VBAで「,」⇒「.」へ置換後、タグ区切りでテキスト保存したい。 お世話になっております。 VBAで下記を行いたいと考えております。 全体の流れとしては、テキストを読み込み⇒エクセル上で編集⇒テキスト保存です。 そのエクセル上で編集⇒テキスト保存で悩んでおります。 編集した複数のシートを、個別にタブ区切りのテキストファイルに保存したいと考えております。 出力する際に、小数点の「,」⇒「.」に変換します。 ※小数点を「,」として利用しています(海外対応) 編集するシートは全てのセルが文字列形式になっており、列も行も読み込むテキストによって可変なので、統一されているわけではありません。 最終行はA列ではなくB列でカウントします。 全てのセルに値が入っているわけではなく、空白もあります。 また、各セルには「0.00000」や「02.24」等の数値も入っており、数値形式にしてしまうと0が消えてしまうので、全てのセルを文字列形式として編集しています。 なお、小数点以下の桁数も可変です。 つまり、小数点が「,」となっているのを「.」になおし、タブ区切りのテキストファイルとして保存したいのです。 出力する際に、いったん別ブックに保存⇒不要なシートを削除⇒タブ区切りで保存はできたのですが、自分があまりVBAに詳しくないせいか、これでは文字列形式で保存されなかったため、シートを新規ブックにコピー⇒タグ区切りで保存に変更しました。 しかし、これではcells.replace ~で置換すると、「00,000」が「0」になってしまいました。 ※「22,222」等は問題ないのですが……何故かは分かりませんでした。 ファイルとしては20000万行~25000行程度です。 列としては40列前後になります。 あまりVBAには詳しくないので、まとはずれな事を言っているかもしれません。 何か良い方法はありますでしょうか? 宜しくお願いいたします。

  • 区切り文字を配列に格納する方法を教えて下さい。

    区切り文字を配列に格納する方法を教えて下さい。 $array[] = "abc,1981,1,12"; $array[] = "def,1982,2,18"; $array[] = "ghi,1991,4,12"; list($name[$i],$yy[$i],$mm[$i],$dd[$i]) = split("\,",$array[$i]); でループさせればそれぞれの変数に代入できますが、例えば $name["abc"]["yy"] = "1981"; $name["abc"]["mm"] = "1"; $name["abc"]["dd"] = "12"; のように分解するにはどうすれば良いでしょうか?

    • 締切済み
    • PHP
  • (VBA)Split関数を使った文字列の区切りについて教えて頂けますでしょうか?

    VBA初心者でSplit関数を使った文字列の区切りがどうしてもうまくいかず非常に困っております。 アドバイス頂けますでしょうか。宜しくお願い致します。 詳細を説明させて頂くと、 (1)エクセルシートのA2セルからA??までの各セルにスペースを含んだ文字列がそれぞれ入力されており、そのそれぞれのセルをスペースで区切ってまず表示させる。 ※データは常にシートのA2からはじまりA3, A4,・・・と不特定に数十行あります (具体例は添付ファイルをご覧頂けますと幸いです。※画像が多少見づらいのですが、画面上のほうがもともとの表で、下の方が完成させたいイメージです。) そして、実際にトライしてみたVBAのソース・・・(本当お恥ずかしいというか 情けないですが。。) Sub data_split() Dim buf As String, tmp, cnt As Long, I As Long cnt = 2 buf = ThisWorksheet.Cells(cnt, 1).Value 'ループ処理(1)(2行目からセルが空になるまで行う処理) Do Until Cells(cnt, 1) = "" cnt = cnt + 1 tmp = split(buf, "") ' データ(文字列)をスペースで区切って出力。 For I = 0 To UBound(tmp) Cells(cnt, I + 1) = tmp(I) Next I Loop End Sub (2)A列からD列までの文字列はそのままで、E列以降(F,G、H・・・)に入った文字列はすべてまとめてE列の各セルに入力させたい。 'AからDまでのセルに入ったセルはそのままでよい。 'E以降の区切られたデータは全部Hセルに入力する VBA初心者なのですが、仕事上、取り急ぎこのようなイメージのVBAを作成しないといけないのですが、本やサイトを見ていろいろと試みているのですがどうしてもうまくいかず非常に困っております。。どうぞ宜しくお願い致します。 参考にしたサイト:http://officetanaka.net/excel/vba/tips/tips62.htm

  • C# 文字列の分割

    VS2005を使用しているものです。 複数のURL(入力)を格納したString型の配列があるのですが、 この配列から各要素(URL)の最後尾にあるファイル名だけを 取り出して別のString型の配列に入れたいのですが Splitなどを駆使すればよいのでしょうか? 例 C:\○○○\▲▲▲\××.拡張子 (元の配列の要素の一例)   などから××.拡張子の文字列だけを取り出して   別の配列に格納する感じです。 splitを使う際は\などを区切りに考えています。 for文の中でsplitを駆使しようと考えたのですが、分割した文字列を別で配列に格納して、その最後尾の要素だけ取り出したいのですが、URLの長さは入力によってまちまちなのでどのようにして取り出せばよいか困っています。 勉強不足で恐れ入りますが、何かご教授願えれば幸いです。

  • Perl、区切り文字で配列に格納したい

    LWP::UserAgentでperlスクリプトから別のスクリプトを呼び出して my $val print $res->as_string; で目的の値を取得したんですが値の前半部分にhttpヘッダーが入っており これを撮り省きたいです。 データの内容はバイナリなので$valの中の改行コードを区切り文字として 配列に格納し末尾の配列の値だけ取りだそうと思っています。 それで指定した区切り文字で配列に格納する方法を調べたのですが よくわからず教えていただけないでしょうか? phpでいうところのexplode関数みたいなことがやりたいです。

    • ベストアンサー
    • Perl
  • 改行入り変数を改行を残したまま改行区切りで配列に入れる方法

    file()関数と同様の事を、ファイル名を指定ではなく変数名を指定して行いたいのですが、explode()関数だと改行(区切り文字)は削除されて配列に格納されてしまいます。とりあえず以下の2つの方法しか思いつかないのですが、どちらが効率的でしょうか? 又、他にもっと良い方法ありましたら教えて欲しいです。お願いします。 方法1 explode後、配列を再ループし末尾に改行コードを付与 方法2 strstrとsubstrで変数をカットしながら配列に格納

    • 締切済み
    • PHP
  • エクセルで保存する形式としてcsvやタブ区切りがありますが、任意の文字

    エクセルで保存する形式としてcsvやタブ区切りがありますが、任意の文字、例えば「#」などで区切って保存する方法はないでしょうか? マクロでできるのであればその方法をご教授ください。 よろしくお願いします。

専門家に質問してみよう