[M1 Mac, Big Sur 11.6.7, clang 13.0.0, NO IDE]
[C++] 96のコードを列挙型 enumを使って書き直しました。これで文字種を直接指定でき、対応するインデックス番号を覚える必要がなくなります。
こちらのswitch文の方がif文よりも洗練された感じですが、条件ごとにいちいちbreakを入れるので見た目は今ひとつです。
今月はstructとenumの作例を作ることを課題の一つにしており、これでクリアです。
#include <cppstd.h> // 自製c++標準ライブラリ群
string hiragana;
string expr;
enum CharType{
NUMBER,
ALPHABET,
HIRAGANA,
KATAKANA,
KANJI
};
string narrow(const wstring &src) {
char *mbs = new char[src.length() * MB_CUR_MAX + 1];
wcstombs(mbs, src.c_str(), src.length() * MB_CUR_MAX + 1);
return mbs;
delete [] mbs;
}
wstring wide(const string &src) {
wchar_t *wcs = new wchar_t[src.length() + 1];
mbstowcs(wcs, src.c_str(), src.length() + 1);
return wcs;
delete [] wcs;
}
string extract(string str, CharType ct){
switch (ct)
{
case NUMBER:{
expr = "[0-9]+"; // 数字
break;
}
case ALPHABET:{
expr = "[a-zA-Z]+"; // 英字
break;
}
case HIRAGANA:{
expr = "[\\u3041-\\u309F]+"; // ひらがな
break;
}
case KATAKANA:{
expr = "[\\u30A0-\\u30FF]+"; // カタカナ
break;
}
case KANJI:{
expr = "[\\u4E00-\\u9FFF]+"; // 漢字
break;
}
}
wstring wstr = wide(str);
wstring wexpr = wide(expr);
std::wregex we(wexpr);
std::wsmatch wm;
if(std::regex_search(wstr, wm, we)){
hiragana = narrow(wm.str());
}
return hiragana;
}
int main()
{
setlocale(LC_CTYPE, "");
string test = "日本語ハローわーるどHelloはろー[123]";
string number = extract(test, NUMBER);
string alphabet = extract(test, ALPHABET);
string hiragana = extract(test, KATAKANA);
string katakana = extract(test, HIRAGANA);
string kanji = extract(test, KANJI);
cout << "数字 " << number << endl;
cout << "英字 " << alphabet << endl;
cout << "ひらがな " << hiragana << endl;
cout << "カタカナ " << katakana << endl;
cout << "漢字 " << kanji << endl;
}
--------------------------------------------------
出力
--------------------------------------------------
数字 123
英字 Hello
ひらがな ハロー
カタカナ わ
漢字 日本語