Edited at

c++ builder XE4, 10.2 Tokyo > 正規表現 > 特定の1文字だけ違うものを許容する

More than 1 year has passed since last update.


動作確認

C++ Builder XE4


"あいうえお"

"あいええお"

上記の両方ともをtrueとするような判断を行う。

"あい[任意の1文字]えお"を許容したい。


code

関連 http://www.megasoft.co.jp/mifes/seiki/

関連 http://qiita.com/7of9/items/61955e00d0138e272a1a


Unit1.cpp

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include <System.RegularExpressions.hpp>

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

#ifdef _WIN32 && !defined(_WIN64)
#pragma alias "toupper" = "_toupper"
#pragma alias "tolower" = "_tolower"
#pragma alias "isupper" = "_isupper"
#pragma alias "isalnum" = "_isalnum"
#pragma alias "isalpha" = "_isalpha"
#pragma alias "iscntrl" = "_iscntrl"
#pragma alias "isdigit" = "_isdigit"
#pragma alias "isgraph" = "_isgraph"
#pragma alias "isleadbyte" = "_isleadbyte"
#pragma alias "islower" = "_islower"
#pragma alias "isprint" = "_isprint"
#pragma alias "ispunct" = "_ispunct"
#pragma alias "isspace" = "_isspace"
#pragma alias "isxdigit" = "_isxdigit"
#pragma alias "strchr" = "_strchr"
#pragma alias "strncmp" = "_strncmp"
#pragma alias "memcmp" = "_memcmp"
#pragma alias "memmove" = "_memmove"
#endif

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{

String strA = L"あいうえお";
String strB = L"あいええお";

String forms[3] = {
L"あい.*えお",
L"あい.えお",
L"あい.うお",
};

bool res;
String msg;

for(int fi=0; fi<3; fi++) {
res = TRegEx::IsMatch(strA, forms[fi]);
msg = "strA:" + BoolToStr(res);
OutputDebugString(msg.c_str());
res = TRegEx::IsMatch(strB, forms[fi]);
msg = "strB:" + BoolToStr(res);
OutputDebugString(msg.c_str());
}

}
//---------------------------------------------------------------------------



結果

デバッグ出力: strA:-1 プロセス Project1.exe (1912)

デバッグ出力: strB:-1 プロセス Project1.exe (1912)
デバッグ出力: strA:-1 プロセス Project1.exe (1912)
デバッグ出力: strB:-1 プロセス Project1.exe (1912)
デバッグ出力: strA:0 プロセス Project1.exe (1912)
デバッグ出力: strB:0 プロセス Project1.exe (1912)

-1となっているのはres==trueの時。

forms[1](=L"あい.えお")の正規表現で対応できそう。


特定の2文字に対して任意文字許容

1文字だけであれば、その場所の情報を使ってSubString()などで文字列を分離して、Pos()などを使えば対応はできそう。

正規表現を使う理由としては、許容する任意の文字の数が1から増えた時にも同じ処理で済ませられるという狙い。


Unit1.cpp

void __fastcall TForm1::Button1Click(TObject *Sender)

{

String strA = L"あいうえおかきくけこ";
String strB = L"あいええおききくけこ";
String strC = L"あいええすききくけこ";

String form = L"あい.えお.きくけこ";

bool res;
String msg;

res = TRegEx::IsMatch(strA, form);
msg = "strA:" + BoolToStr(res);
OutputDebugString(msg.c_str());

res = TRegEx::IsMatch(strB, form);
msg = "strB:" + BoolToStr(res);
OutputDebugString(msg.c_str());

res = TRegEx::IsMatch(strC, form);
msg = "strB:" + BoolToStr(res);
OutputDebugString(msg.c_str());
}



結果

デバッグ出力: strA:-1 プロセス Project1.exe (3456)

デバッグ出力: strB:-1 プロセス Project1.exe (3456)
デバッグ出力: strB:0 プロセス Project1.exe (3456)


補足

過去に実装したコードを見直すと、文字列の中の単位(cmなど)を取り除いて比較する実装をしていた。30行近いコードになっている。

正規表現を使っていれば数行で実装できる。


10.2 Tokyo


動作確認

RAD Studio 10.2 Tokyo Update 2 (追記: 2017/12/27)


10.2 Tokyoでは#ifdef _WIN32 && !defined(_WIN64)の部分は不要になる。

C++ Builder 10.2 Tokyo > 正規表現 > XE4で出ていたエラーは解消 > toupperが....System.RegularExpressionsAPIから参照されています | (XE4から10.2Tokyoへの移行)


Unit1.cpp

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"

#include <System.RegularExpressions.hpp>

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{

}

void __fastcall TForm1::Button1Click(TObject *Sender)
{
String strA = L"あいうえおかきくけこ";
String strB = L"あいええおききくけこ";
String strC = L"あいええすききくけこ";

String form = L"あい.えお.きくけこ";

bool res;
String msg;

res = TRegEx::IsMatch(strA, form);
msg = "strA:" + BoolToStr(res);
OutputDebugString(msg.c_str());

res = TRegEx::IsMatch(strB, form);
msg = "strB:" + BoolToStr(res);
OutputDebugString(msg.c_str());

res = TRegEx::IsMatch(strC, form);
msg = "strB:" + BoolToStr(res);
OutputDebugString(msg.c_str());
}
//---------------------------------------------------------------------------