C 文字列操作 新しいページはコチラ
提供: yonewiki
(→文字列の検索と置換) |
(→文字列の検索と置換) |
||
3,818行: | 3,818行: | ||
UErrorCode status = U_ZERO_ERROR; | UErrorCode status = U_ZERO_ERROR; | ||
int nFindCnt = 0; | int nFindCnt = 0; | ||
+ | |||
+ | printf("★正規表現検索\n"); | ||
UnicodeString regex = L"[,/とやも]";//正規表現検索文字 | UnicodeString regex = L"[,/とやも]";//正規表現検索文字 | ||
RegexPattern* pattern = RegexPattern::compile(regex, error, status);//パターンを登録(コンパイル) | RegexPattern* pattern = RegexPattern::compile(regex, error, status);//パターンを登録(コンパイル) | ||
assert( U_SUCCESS(status) ); | assert( U_SUCCESS(status) ); | ||
− | + | ||
UnicodeString input = L"リンゴとミカン/ナシとモモ,ごはんやおかず/おさけもつまみ,programと技術"; | UnicodeString input = L"リンゴとミカン/ナシとモモ,ごはんやおかず/おさけもつまみ,programと技術"; | ||
assert( U_SUCCESS(status) ); | assert( U_SUCCESS(status) ); | ||
− | + | RegexMatcher* matcher = pattern->matcher(input, status); | |
+ | printf("★パターンマッチ結果出力\n"); | ||
while ( matcher->find() ) { | while ( matcher->find() ) { | ||
//それぞれのマッチグループの出力。パターンに部分一致(.)が無い場合はつねにグループは1で要素0番のみ | //それぞれのマッチグループの出力。パターンに部分一致(.)が無い場合はつねにグループは1で要素0番のみ | ||
3,839行: | 3,842行: | ||
std::wcout << std::endl; | std::wcout << std::endl; | ||
} | } | ||
− | + | ||
//分割した回数のUnicodeString変数の配列を確保して分割結果を配列に格納。 | //分割した回数のUnicodeString変数の配列を確保して分割結果を配列に格納。 | ||
+ | printf("★検索された分割文字トークンの数\n"); | ||
std::wcout << nFindCnt << std::endl; | std::wcout << nFindCnt << std::endl; | ||
+ | printf("\n"); | ||
+ | |||
UnicodeString* pfruits = new UnicodeString[nFindCnt + 1]; | UnicodeString* pfruits = new UnicodeString[nFindCnt + 1]; | ||
− | + | int32_t splits = pattern->split(input, pfruits, nFindCnt + 1, status);//登録されたパターンで分割処理 | |
//splitの引数には入力文字列,要素が確保された出力文字列配列変数,分割数,実行結果 | //splitの引数には入力文字列,要素が確保された出力文字列配列変数,分割数,実行結果 | ||
− | + | ||
assert( U_SUCCESS(status) ); | assert( U_SUCCESS(status) ); | ||
− | + | printf("★分割抽出した配列の出力\n"); | |
//分割によりそれぞれに格納された文字を文字列配列の全出力で確認 | //分割によりそれぞれに格納された文字を文字列配列の全出力で確認 | ||
for ( int32_t i = 0; i < splits; i++ ) { | for ( int32_t i = 0; i < splits; i++ ) { | ||
std::wcout << pfruits[i].getTerminatedBuffer() << std::endl; | std::wcout << pfruits[i].getTerminatedBuffer() << std::endl; | ||
− | std::wcout << (*(pfruits + i)).getTerminatedBuffer() << std::endl; | + | //std::wcout << (*(pfruits + i)).getTerminatedBuffer() << std::endl;こうやって表現しても同じ。 |
} | } | ||
− | + | printf("\n"); | |
+ | |||
//★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
// 正規表現置換 | // 正規表現置換 | ||
3,859行: | 3,866行: | ||
UnicodeString replacement = L"+"; | UnicodeString replacement = L"+"; | ||
+ | |||
/* | /* | ||
* 先頭置換 : replaceFirst | * 先頭置換 : replaceFirst | ||
*/ | */ | ||
− | result = matcher->replaceFirst(replacement, status); | + | printf("★先頭置換\n"); |
+ | UnicodeString result = matcher->replaceFirst(replacement, status); | ||
assert( U_SUCCESS(status) ); | assert( U_SUCCESS(status) ); | ||
std::wcout << result.getTerminatedBuffer() << std::endl; | std::wcout << result.getTerminatedBuffer() << std::endl; | ||
− | + | ||
/* | /* | ||
* 一括置換 : replaceAll | * 一括置換 : replaceAll | ||
*/ | */ | ||
+ | printf("★一括置換\n"); | ||
result = matcher->replaceAll(replacement, status); | result = matcher->replaceAll(replacement, status); | ||
assert( U_SUCCESS(status) ); | assert( U_SUCCESS(status) ); | ||
std::wcout << result.getTerminatedBuffer() << std::endl; | std::wcout << result.getTerminatedBuffer() << std::endl; | ||
− | + | ||
/* | /* | ||
* 追記置換 : appendReplacement/appendAll 前方から逐次置換してresultに追加していく方式 | * 追記置換 : appendReplacement/appendAll 前方から逐次置換してresultに追加していく方式 | ||
*/ | */ | ||
+ | printf("★追記置換\n"); | ||
result = L""; | result = L""; | ||
matcher->reset(); | matcher->reset(); | ||
3,884行: | 3,895行: | ||
std::wcout << result.getTerminatedBuffer() << std::endl; | std::wcout << result.getTerminatedBuffer() << std::endl; | ||
} | } | ||
− | + | ||
− | + | ||
//最後の置換以降の残った文字列を追加 | //最後の置換以降の残った文字列を追加 | ||
matcher->appendTail(result); | matcher->appendTail(result); | ||
std::wcout << result.getTerminatedBuffer() << std::endl; | std::wcout << result.getTerminatedBuffer() << std::endl; | ||
− | + | ||
− | + | printf("\n"); | |
+ | |||
//★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
// 部分一致 | // 部分一致 | ||
//★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
− | |||
/* | /* | ||
* 部分マッチ"(.)"の置換 | * 部分マッチ"(.)"の置換 | ||
− | */ | + | */ |
+ | regex = L"(.)[,/とやも]";//正規表現検索文字 区切り文字の一文字手前を置換 | ||
+ | pattern = RegexPattern::compile(regex, error, status); | ||
+ | |||
+ | matcher = pattern->matcher(input, status); | ||
+ | printf("★パターンマッチ結果出力\n"); | ||
+ | while ( matcher->find() ) { | ||
+ | //それぞれのマッチグループの出力。パターンに部分一致(.)が無い場合はつねにグループは1で要素0番のみ | ||
+ | for ( int32_t i = 0; i <= matcher->groupCount(); i++ ) { | ||
+ | std::wcout << L"[" << matcher->start(i,status) | ||
+ | << L"," << matcher->end(i,status) | ||
+ | << L"]" << matcher->group(i,status).getTerminatedBuffer() | ||
+ | << std::endl; | ||
+ | assert( U_SUCCESS(status) ); | ||
+ | } | ||
+ | //whileループ回数をカウントして分割数を記録 | ||
+ | nFindCnt++; | ||
+ | std::wcout << std::endl; | ||
+ | } | ||
+ | |||
+ | |||
typedef std::pair<int32_t,int32_t> range_type; | typedef std::pair<int32_t,int32_t> range_type; | ||
std::vector<range_type> matches; | std::vector<range_type> matches; | ||
3,907行: | 3,938行: | ||
assert( U_SUCCESS(status) ); | assert( U_SUCCESS(status) ); | ||
} | } | ||
− | + | replacement = L"★";//伏字に置換 | |
− | + | result = input; | |
// 末尾から置換 | // 末尾から置換 | ||
while ( !matches.empty() ) { | while ( !matches.empty() ) { | ||
3,916行: | 3,947行: | ||
replacement); | replacement); | ||
} | } | ||
+ | printf("★部分一致パターンの置換結果出力\n"); | ||
std::wcout << result.getTerminatedBuffer() << std::endl; | std::wcout << result.getTerminatedBuffer() << std::endl; | ||
3,923行: | 3,955行: | ||
− | + | return 0; | |
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
出力結果 | 出力結果 | ||
<syntaxhighlight lang="text"> | <syntaxhighlight lang="text"> | ||
− | + | ★正規表現検索 | |
− | + | ★パターンマッチ結果出力 | |
[3,4]と | [3,4]と | ||
− | |||
[7,8]/ | [7,8]/ | ||
− | |||
[10,11]と | [10,11]と | ||
− | |||
[13,14], | [13,14], | ||
− | |||
[17,18]や | [17,18]や | ||
− | |||
[21,22]/ | [21,22]/ | ||
− | |||
[25,26]も | [25,26]も | ||
− | |||
[29,30], | [29,30], | ||
− | |||
[37,38]と | [37,38]と | ||
+ | ★検索された分割文字トークンの数 | ||
9 | 9 | ||
− | + | ||
+ | ★分割抽出した配列の出力 | ||
リンゴ | リンゴ | ||
− | |||
ミカン | ミカン | ||
− | |||
ナシ | ナシ | ||
− | |||
モモ | モモ | ||
− | |||
ごはん | ごはん | ||
おかず | おかず | ||
− | |||
− | |||
おさけ | おさけ | ||
つまみ | つまみ | ||
− | |||
− | |||
program | program | ||
技術 | 技術 | ||
− | + | ||
+ | ★先頭置換 | ||
リンゴ+ミカン/ナシとモモ,ごはんやおかず/おさけもつまみ,programと技術 | リンゴ+ミカン/ナシとモモ,ごはんやおかず/おさけもつまみ,programと技術 | ||
+ | ★一括置換 | ||
リンゴ+ミカン+ナシ+モモ+ごはん+おかず+おさけ+つまみ+program+技術 | リンゴ+ミカン+ナシ+モモ+ごはん+おかず+おさけ+つまみ+program+技術 | ||
+ | ★追記置換 | ||
リンゴ+ | リンゴ+ | ||
リンゴ+ミカン+ | リンゴ+ミカン+ | ||
3,990行: | 4,011行: | ||
リンゴ+ミカン+ナシ+モモ+ごはん+おかず+おさけ+つまみ+program+技術 | リンゴ+ミカン+ナシ+モモ+ごはん+おかず+おさけ+つまみ+program+技術 | ||
− | + | ★パターンマッチ結果出力 | |
+ | [2,4]ゴと | ||
+ | [2,3]ゴ | ||
+ | |||
+ | [6,8]ン/ | ||
+ | [6,7]ン | ||
+ | |||
+ | [9,11]シと | ||
+ | [9,10]シ | ||
+ | |||
+ | [12,14]モ, | ||
+ | [12,13]モ | ||
+ | |||
+ | [16,18]んや | ||
+ | [16,17]ん | ||
+ | |||
+ | [20,22]ず/ | ||
+ | [20,21]ず | ||
+ | |||
+ | [24,26]けも | ||
+ | [24,25]け | ||
+ | |||
+ | [28,30]み, | ||
+ | [28,29]み | ||
+ | |||
+ | [36,38]mと | ||
+ | [36,37]m | ||
+ | リン★とミカ★/ナ★とモ★,ごは★やおか★/おさ★もつま★,progra★と技術 | ||
</syntaxhighlight> | </syntaxhighlight> | ||