Top / Programming / C++Builder / 文字列を分割する

文字列を分割する

C++Builderで文字列を分割する方法を紹介します。

StrUtils.SplitString関数

StrUtils.SplitString関数はC++Builder XEで追加された関数です。

文字列を「|」で分割するする例

#include <StrUtils.hpp>

TStringDynArray array = SplitString("イージス|バスター|デュエル|ブリッツ|ストライク", "|");
for (int i = 0; i < array.Length; ++i)
   std::wcout << array[i].c_str() << std::endl;

複数の区切り文字で分割する例

#include <StrUtils.hpp>

TStringDynArray array = SplitString("2011/02/09 20:19:33", "/ :");
for (int i = 0; i < array.Length; ++i)
   std::wcout << array[i].c_str() << std::endl;

TRegEx::Split関数

TRegEx::Split関数はC++Builder XEで追加された正規表現の関数です。

C++Builder XE以前のバージョンをお使いの場合は、TRegExの代わりにSkRegExpを使用します。

正規表現で区切り文字を指定します。

文字列を「|」で分割するする例

#include <RegularExpressions.hpp>
//#include "SkRegularExpressions.hpp" //SkRegExp

TStringDynArray array = TRegEx::Split("イージス|バスター|デュエル|ブリッツ|ストライク", "\|");
for (int i = 0; i < array.Length; ++i)
  std::wcout << array[i].c_str() << std::endl;

複数の区切り文字で分割する例

#include <RegularExpressions.hpp>
//#include "SkRegularExpressions.hpp" //SkRegExp

TStringDynArray array = TRegEx::Split("2011/02/09 20:19:33", "[/ :]");
for (int i = 0; i < array.Length; ++i)
  std::wcout << array[i].c_str() << std::endl;

boost::split関数

boostのsplit関数も使用できます。

文字列を「|」で分割する例

#include <boost/algorithm/string.hpp>
#include <boost/foreach.hpp>

std::list<std::wstring> results; //分割結果を格納する変数
boost::split(results, L"イージス|バスター|デュエル|ブリッツ|ストライク", boost::is_any_of(L"|"));
BOOST_FOREACH(std::wstring p, results)
  std::wcout << p << std::endl;

複数の区切り文字で分割する例

#include <boost/algorithm/string.hpp>
#include <boost/foreach.hpp>

std::list<std::wstring> results;
boost::split(results, L"2011/02/09 20:19:33", boost::is_any_of(L"/ :"));
BOOST_FOREACH(std::wstring p, results)
  std::wcout << p << std::endl;

空白文字で分割する例

#include <boost/algorithm/string.hpp>
#include <boost/foreach.hpp>

std::list<std::wstring> results;
boost::split(results, L"More Effective C++", boost::is_space());
BOOST_FOREACH(std::wstring p, results)
  std::wcout << p << std::endl;

TStrings.DelimitedTextプロパティ

TStringsのDelimitedTextを使って、文字列を分割することができます。

TStringList* list = new TStringList();
list->StrictDelimiter = true;
list->Delimiter = L'|';
list->DelimitedText = "イージス|バスター|デュエル|ブリッツ|ストライク";
for (int i = 0; i < list->Count; ++i)
  std::wcout << list->Strings[i].c_str() << std::endl;

StrictDelimiterプロパティがfalseの場合、スペースでも分割されてしまいます。
QuoteCharプロパティの値にも気をつけてください。

sscanf,swscanf関数

ブログのコメント欄で教えてもらいました。
C言語の関数であるsscanf,swscanf関数も使えます。

#include <stdio.h>

wchar_t c[5][10];
swscanf(
  L"イージス バスター デュエル ブリッツ ストライク", //空白区切り
  L"%s %s %s %s %s",
  &c[0], &c[1], &c[2], &c[3], &c[4]);

for (int i = 0; i < 5; ++i) wprintf(L"%s\n", c[i]);

std::getline()関数

getline()関数は第三引数に区切り文字を指定することができます。

#include <sstream>
#include <iostream>
#include <string>

std::wistringstream iss(L"イージス|バスター|デュエル|ブリッツ|ストライク");
std::wstring tmp;
while (std::getline(iss, tmp, L'|')) std::wcout << tmp << std::endl;

ExtractStrings()関数

ExtractStrings()関数というのを見つけました。

//部分文字列を区切る区切り文字と
TSysCharSet Separators = TSysCharSet() << '|' << ',';
//文字列の先頭にある場合にContentの分解時に無視される文字
TSysCharSet WhiteSpace = TSysCharSet();
//部分文字列に分解される文字列
UnicodeString Content = "イージス|バスター,デュエル|ブリッツ|ストライク";
//分解されたすべての部分文字列が追加される文字列リスト
TStringList* Strings = new TStringList();

int Ret = ExtractStrings(Separators, WhiteSpace, Content.c_str(), Strings);

JCLのStrToStrings関数

#include <JclStrings.hpp>
//AnsiString版を使うときはJclAnsiStrings.hppを使用します。
//#include <JclAnsiStrings.hpp>

extern PACKAGE void __fastcall StrToStrings(
  System::UnicodeString S, 
  System::UnicodeString Sep, 
  System::Classes::TStrings* const List, 
  const bool AllowEmptyString = true);

引数Sは分割する文字列、引数Sepは区切り文字、引数Listは分割した文字列を登録するリストです。
引数AllowEmptyStringがfalseのときは空文字は結果から除外されます。

サンプルプログラム

//分割する文字列
UnicodeString S = "イージス||バスター||||デュエル|ブリッツ|ストライク";
//区切り文字
UnicodeString Sep = "|";
//分割した文字列のリスト
TStringList* List = new TStringList();
//AllowEmptyStringがtrueのとき
StrToStrings(S, Sep, List, true);
Memo1->Lines->Assign(List);
//AllowEmptyStringがfalseのとき
StrToStrings(S, Sep, List, false);
Memo2->Lines->Assign(List);

更新履歴