[C++] 96 文字列から各文字種を取り出す動的ライブラリ dylib

[M1 Mac, Big Sur 11.6.7, clang 13.0.0, NO IDE]

文字列から数字、英字、ひらがな、カタカナ、漢字をそれぞれ取り出す動的ライブラリを作成しました。

ただし最初の単語しか認識せず、2番目以降は取り出しできない限定機能です。文字列全体からもれなく取り出すのであればPythonの方が簡単に書けそうです。

このような便利な動的ライブラリを作成していくとおのずと主言語はC++になっていくでしょう。

#include <cppstd.h> // 自製c++標準ライブラリ群

class CharExtract{
public:
string narrow(const wstring &src);
wstring wide(const string &src);
string extract(string str,int num);
};
#include <cppstd.h> // 自製c++標準ライブラリ群
#include <CharExtract.h>

string hiragana;
string expr;

string CharExtract::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;
}

wstring CharExtract::wide(const string &src) {
	wchar_t *wcs = new wchar_t[src.length() + 1];
	mbstowcs(wcs, src.c_str(), src.length() + 1);
	return wcs;
}

string CharExtract::extract(string str, int num){
    if (num == 0){
        expr = "[0-9]+"; // 数字
    } else if (num == 1){
        expr = "[a-zA-Z]+"; // 英字
    } else if (num == 2){
        expr = "[\\u3041-\\u309F]+"; // ひらがな
    } else if (num == 3) {
        expr = "[\\u30A0-\\u30FF]+"; // カタカナ
    } else if (num == 4){
        expr = "[\\u4E00-\\u9FFF]+"; // 漢字
    }

    wstring wstr = wide(str);
    wstring wexpr = wide(expr);

    std::wregex we(wexpr);
    std::wsmatch wm;
    if(std::regex_search(wstr, wm, we)){
        character = narrow(wm.str());
    }
    return character;
}
clang++ -dynamiclib -o CharExtract.dylib \
CharExtract.cpp \
-I/code/cpp/mylib/include -std=c++17
#include <cppstd.h> // 自製c++標準ライブラリ群
#include <CharExtract.h>

CharExtract CE;

int main()
{
    setlocale(LC_CTYPE, "");

    string test = 日本語ハローわーるどHelloはろー[123]";
    
    string number = CE.extract(test, 0);
    string alphabet = CE.extract(test, 1);
    string hiragana = CE.extract(test, 2);
    string katakana = CE.extract(test, 3);
    string kanji = CE.extract(test, 4);

    cout << "数字 " << number << endl;
    cout << "英字 " << alphabet << endl;
    cout << "ひらがな " << hiragana << endl;
    cout << "カタカナ " << katakana << endl;
    cout << "漢字 " << kanji << endl;
}
--------------------------------------------------
出力
--------------------------------------------------
数字 123
英字 Hello
ひらがな わ     // 長音"ー"はカタカナ扱い
カタカナ ハロー
漢字 日本語

[C++] 95 文字列からひらがなを取り出す wregex

[M1 Mac, Big Sur 11.6.7, clang 13.0.0, NO IDE]

前回は開発速度を優先して泥臭い手法を用いましたが、今回はよりプログラマらしい内容に書き直しました。

対象文字列と全てのひらがなをstringからwstringに変換し、正規表現を使って対象文字列からひらがなを取り出しました。ひらがな設定は文字列リテラルを書き出すのではなくunicodeを使っています。

setlocaleでロケールを設定しないとひらがなを扱えないので要注意です。

マルチバイト文字の扱いにくさはC/C++の弱点の一つですね。Visual C++やC#など、Microsoftはその辺のフォローが行き届いているように思います。まあそれでもWindowsをメインOSにしようとは思いませんが..

#include <cppstd.h> // 自製c++標準ライブラリ群

string hiragana;

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;
}

wstring wide(const string &src) {
	wchar_t *wcs = new wchar_t[src.length() + 1];
	mbstowcs(wcs, src.c_str(), src.length() + 1);
	return wcs;
}

string hiragana_extract(string str){
    string expr = "[\\u3041-\\u309F]+"; // ひらがな

    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 hiragana = hiragana_extract(test);

    cout << "ひらがな抽出 " << hiragana << endl;
}
--------------------------------------------------
出力
--------------------------------------------------
ひらがな抽出 みずあさぎ

参考サイト1
参考サイト2