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

```txt:動作確認
C++ Builder XE4
```

"あいうえお"
"あいええお"

上記の両方ともをtrueとするような判断を行う。
"あい`[任意の１文字]`えお"を許容したい。

## 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());
	}

}
//---------------------------------------------------------------------------
```

```txt:結果
デバッグ出力: 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());
}
```

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

### 補足

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

## 10.2 Tokyo

```txt:動作確認
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への移行)](https://qiita.com/7of9/items/05388eb873e8808ae8cf)

```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());
}
//---------------------------------------------------------------------------
```