MECSUtils リファレンス
MECSUtils は文字単位での文字列操作及び、文字エンコード変換を行うユニットで、正式には Delphi 2007 以降に対応しています。
(正式対応していませんが、Delphi 6 ~ BDS 2006 でもコンパイルできる事を確認しています)
ANSI 版 Delphi の SysUtils / StrUtils 名前空間にある類似関数は文字エンコード変換がサロゲートペアに対応しておらず、Unicode 版 Delphi の AnsiStrings / SysUtils / StrUtils 名前空間にある類似関数はサロゲートペアを考慮した文字列操作に対応していません。
ANSI 版 / Unicode 版 Delphi で同名の関数を使って同等の処理可能にするのが MECSUtils です。
最新版は、CodeCentral から入手する事ができます。http://cc.embarcadero.com/item/26061
Codepage/CharSet/Locale ルーチン
TBytes ルーチン
AnsiString ルーチン
UnicodeString / WideString ルーチン
Common ルーチン
結合文字列 ルーチン
Convert ルーチン
HTML ルーチン
CodePageToFontCharset 関数はコードページから TFont.CharSet を導き出します。
分野の指定
Codepage/CharSet/Locale ルーチン
Delphi の構文:
function CodePageToFontCharset(CodePage: DWORD): TFontCharset;
説明:
CodePageToFontCharset 関数はコードページから TFont.CharSet を導き出します。CodePage で指定したコードページから、対応すると思われる TFont.CharSet を返します。
FontCharsetToCodePage 関数は TFont.CharSet からコードページを導き出します。
分野の指定
Codepage/CharSet/Locale ルーチン
Delphi の構文:
function FontCharsetToCodePage(FontCharset: TFontCharset): DWORD;
説明:
FontCharsetToCodePage 関数は TFont.CharSet からコードページを導き出します。FontCharset で指定した TFont.CharSet から、対応すると思われるコードページを返します。
IsFarEastCharSet 関数は TFont.CharSet が東アジアのものかどうかを判定します。
分野の指定
Codepage/CharSet/Locale ルーチン
Delphi の構文:
function IsFarEastCharSet(CharSet: TFontCharSet): Boolean;
説明:
IsFarEastCharSet 関数は TFont.CharSet が東アジアのものかどうかを判定します。戻り値を MecsIsFullWidth 関数に設定する事で、TFont.CharSet から文字幅の計算を行う事ができます。
IsFarEastLCID 関数はロケール ID が東アジアのものかどうかを判定します。
分野の指定
Codepage/CharSet/Locale ルーチン
Delphi の構文:
function IsFarEastLCID(Locale: LCID): Boolean;
説明:
IsFarEastLCID 関数はロケール ID が東アジアのものかどうかを判定します。戻り値を MecsIsFullWidth 関数に設定する事で、ロケール ID から文字幅の計算を行う事ができます。
IsFarEastLCID 関数は Locale が 香港 (LCID=3076) や シンガポール (LCID=4100) の場合にも True を返します。東アジアという地域としては正しいのですが、これらの地域では公用語が一つではないため、MecsIsFullWidthへ渡す値としては必ずしも正しいとは限りません。
MecsAnsiBytesOf 関数は ANSI 文字列を TBytes へ変換します。
分野の指定
TBytes ルーチン
Unicode 版 Delphi の構文:
function MecsAnsiBytesOf(const Val: RawByteString): TBytes;
ANSI 版 Delphi の構文:
function MecsAnsiBytesOf(const Val: AnsiString): TBytes;
説明:
MecsAnsiBytesOf 関数は ANSI 文字列を TBytes へ変換します。戻り値はヌル終端の TBytes になります。
MecsAnsiBytesOf 関数は AnsiString 用 MecsBytesOf() のラッパーです。
MecsAnsiStringOf 関数は TBytes を ANSI 文字列へ変換します。
分野の指定
TBytes ルーチン
Unicode 版 Delphi の構文:
function MecsAnsiStringOf(const Bytes: TBytes): RawByteString;
ANSI 版 Delphi の構文:
function MecsAnsiStringOf(const Bytes: TBytes): AnsiString;
説明:
MecsAnsiBytesOf TBytes を ANSI 文字列へ変換します。Bytes はヌル終端である必要があります。
MecsAnsiBytesOf 関数は AnsiString 用 MecsStringOf() のラッパーです。
関連情報:
MecsBytesOf 関数は文字列変数を TBytes へ変換します。
分野の指定
TBytes ルーチン
Unicode 版 Delphi の構文:
function MecsBytesOf(const Val: UnicodeString): TBytes;
function MecsBytesOf(const Val: WideString): TBytes;
function MecsBytesOf(const Val: RawByteString): TBytes;
ANSI 版 Delphi の構文:
function MecsBytesOf(const Val: WideString): TBytes;
function MecsBytesOf(const Val: AnsiString): TBytes;
説明:
MecsBytesOf 関数は文字列変数を TBytes へ変換します。戻り値はヌル終端の TBytes になります。
// Unicode 版 Delphi での例
var
Dmy: String;
S: UnicodeString;
B: TBytes;
i: Integer;
begin
S := 'ABCあいう';
B := BytesOf(S);
Dmy := '';
for i:=Low(B) to High(B) do
Dmy := Dmy + Format('0x%.2x ', [B[i]]);
ShowMessage(Dmy);
end;
|
Unicode 版 Delphi の BytesOf() は引数に UnicodeString 型の変数を与えると、戻り値は "デフォルト ANSI コードページに変換されたバイト列" となり、上記コードは "0x41 0x42 0x43 0x82 0xA0 0x82 0xA2 0x82 0xA4" を返します。
ちょっと混乱しますが、UnicodeString を TBytes に変換するには、BytesOf() ではなく、WideBytesOf() または PlatformBytesOf() を利用します。
// Unicode 版 Delphi での例
var
Dmy: String;
S: UnicodeString;
B: TBytes;
i: Integer;
begin
S := 'ABCあいう';
B := WideBytesOf(S);
Dmy := '';
for i:=Low(B) to High(B) do
Dmy := Dmy + Format('0x%.2x ', [B[i]]);
ShowMessage(Dmy);
end;
|
WideBytesOf() の戻り値は "UTF-16 をバイト列にしたもの" となり、上記コードは "0x41 0x00 0x42 0x00 0x43 0x00 0x42 0x30 0x44 0x30 0x46 0x30" を返します。
// Unicode 版 Delphi での例
var
Dmy: String;
A: AnsiString;
B: TBytes;
i: Integer;
begin
A := AnsiString('ABCあいう');
B := MecsBytesOf(A);
Dmy := '';
for i:=Low(B) to High(B) do
Dmy := Dmy + Format('0x%.2x ', [B[i]]);
ShowMessage(Dmy);
end;
|
MecsBytesOf() の引数に AnsiString 型の変数を与えると、戻り値は "AnsiString をバイト列にしたもの" となり、上記コードは "0x41 0x42 0x43 0x82 0xA0 0x82 0xA2 0x82 0xA4 0x00" を返します。
// Unicode 版 Delphi での例
var
Dmy: String;
S: UnicodeString;
B: TBytes;
i: Integer;
begin
S := 'ABCあいう';
B := MecsBytesOf(S);
Dmy := '';
for i:=Low(B) to High(B) do
Dmy := Dmy + Format('0x%.2x ', [B[i]]);
ShowMessage(Dmy);
end;
|
MecsBytesOf() の引数に UnicodeString 型の変数を与えると、戻り値は "UTF-16 をバイト列にしたもの" となり、上記コードは "0x41 0x00 0x42 0x00 0x43 0x00 0x42 0x30 0x44 0x30 0x46 0x30 0x00 0x00" を返します。
MecsBytesOf() が返す TBytes にヌル終端が付加されているのは、PAnsiChar (引数が AnsiString の場合) や PWideChar (引数が WideString / UnicodeString の場合) でキャストするのを容易にするためです。
RTL の BytesOf() / WideBytesOf() / PlatFormBytesOf() を使い分けるのは面倒なので、MECSUtils では MecsBytesOf() をオーバーロード関数で定義しています。
また、MecsBytesOf() は RTL の類似関数とは異なり、システムロケールを考慮しません。エレメントを単純にバイト列へ変換します。
MecsStringOf 手続きは TBytes を文字列変数へ変換します。
分野の指定
TBytes ルーチン
Unicode 版 Delphi の構文:
procedure MecsStringOf(const Bytes: TBytes; var S: UnicodeString);
procedure MecsStringOf(const Bytes: TBytes; var S: WideString);
procedure MecsStringOf(const Bytes: TBytes; var S: RawByteString);
ANSI 版 Delphi の構文:
procedure MecsStringOf(const Bytes: TBytes; var S: WideString);
procedure MecsStringOf(const Bytes: TBytes; var S: AnsiString);
説明:
MecsStringOf 手続きは TBytes を文字列変数へ変換します。Bytes はヌル終端である必要があります。
// Unicode 版 Delphi での例
var
Dmy: String;
A: AnsiString;
B: TBytes;
i: Integer;
begin
SetLength(B, 6);
B[0] := $81; // 81E6 : ∵
B[1] := $E6;
B[2] := $87; // 879A : ∵
B[3] := $9A;
B[4] := $FA; // FA5B : ∵
B[5] := $5B;
A := StringOf(B);
Dmy := '';
for i:=1 to Length(A) do
Dmy := Dmy + Format('0x%.2x ', [Byte(A[i])]);
ShowMessage(Dmy);
end;
|
Unicode 版 Delphi の StringOf() は戻り値が String (UnicodeString) なので、引数の TBytes が AnsiString を格納していると ラウンドトリップが行われるため、上記コードは "0x81 0xE6 0x81 0xE6 0x81 0xE6" を返します。それ以前に、StringOf() 内部で "デフォルト ANSI->Unicode 変換" が行われています。
また、引数の TBytes が UnicodeString を格納している場合には WideStringOf() / PlatformStringOf() を使います。故に、StringOf() の戻り値は AnsiString でなければならないハズですが、何故か戻り値は UnicodeString となっています。BytesOf() には RawByteString からの変換を行うオーバーロード関数があるのに、その逆を行う事ができない事になります。もちろん、AnsiStringOf() という関数は存在しません。
// Unicode 版 Delphi での例
var
Dmy: String;
A: RawByteString;
B: TBytes;
i: Integer;
begin
SetLength(B, 7);
B[0] := $81; // 81E6 : ∵
B[1] := $E6;
B[2] := $87; // 879A : ∵
B[3] := $9A;
B[4] := $FA; // FA5B : ∵
B[5] := $5B;
B[6] := $00; // ヌル終端
MecsStringOf(B, A);
SetCodePage(A, DefaultAnsiCodePage, False); // デフォルトの ANSI コードページにする
Dmy := '';
for i:=1 to Length(A) do
Dmy := Dmy + Format('0x%.2x ', [Byte(A[i])]);
ShowMessage(Dmy)
end;
|
MecsStringOf() は StringOf() と書式が異なり、関数ではなく手続きとなっています。引数の TBytes が AnsiString を格納していてもラウンドトリップが行われないため、上記コードは "0x81 0xE6 0x87 0x9A 0xFA 0x5B" を返します。
RTL の StringOf() / WideStringOf() / PlatFormStringOf() を使い分けるのは面倒なので、MECSUtils では MecsStringOf() をオーバーロード手続きで定義しています。Unicode 版 Delphi 用 MecsStringOf() に引数が RawByteString のものがあるのは、TBytes があらゆる ANSI のバッファとして利用される事を想定しているからです。
また、MecsStringOf() は RTL の類似関数とは異なり、システムロケールを考慮しません。バイト列を単純にエレメントへ変換します。
MecsWideBytesOf 関数は Unicode 文字列を TBytes へ変換します。
分野の指定
TBytes ルーチン
Unicode 版 Delphi の構文:
function MecsWideBytesOf(const Val: UnicodeString): TBytes;
ANSI 版 Delphi の構文:
function MecsWideBytesOf(const Val: WideString): TBytes;
説明:
MecsWideBytesOf 関数は Unicode 文字列を TBytes へ変換します。戻り値はヌル終端の TBytes になります。
MecsWideBytesOf 関数は UnicodeString 用 MecsBytesOf() のラッパーです。
MecsWideStringOf 関数は TBytes を Unicode 文字列へ変換します。
分野の指定
TBytes ルーチン
Unicode 版 Delphi の構文:
function MecsWideStringOf(const Bytes: TBytes): UnicodeString;
ANSI 版 Delphi の構文:
function MecsWideStringOf(const Bytes: TBytes): WideString;
説明:
"MecsWideStringOf" TBytes を Unicode 文字列へ変換します。Bytes はヌル終端である必要があります。
MecsWideBytesOf 関数は UnicodeString 用 MecsStringOf() のラッパーです。
MecsGetCodePage 関数は AnsiString のコードページを取得します。
分野の指定
AnsiString ルーチン
Unicode 版 Delphi の構文:
function MecsGetCodePage(const S: RawByteString): DWORD;
ANSI 版 Delphi の構文:
function MecsGetCodePage(const S: AnsiString): DWORD;
説明:
MecsGetCodePage 関数は AnsiString のコードページを取得します。Unicode 版 Delphi では、AnsiString のコードページを取得します。ANSI 版 Delphi では MECSUtils.DefaultAnsiCodePage 変数に設定されたコードページ (デフォルトでは規定のコードページ) が返ります。
MecsGetCodePage 関数は AnsiString を扱う関数のデフォルトコードページを特定するのに利用されます。直接呼び出す事はあまりないかもしれません。
MecsGetLeadBytes 関数はマルチバイト AnsiString の LeadByte の一覧を取得します。
分野の指定
AnsiString ルーチン
Delphi の構文:
function MecsGetLeadBytes(CodePage: DWORD = 0): TLeadBytes;
説明:
MecsGetLeadBytes 関数はマルチバイト AnsiString の LeadByte を取得します。LeadByte とはマルチバイト文字の最初の要素 (第 1 バイト目) の事です。マルチバイト文字の 2 番目以降の要素は TrailByte と呼ばれます。in 演算子、または CharInSet 関数でエレメント (文字構成要素) が LeadByte に該当するかどうかを知ることができます。
コードページを指定しなかった場合には、MECSUtils.DefaultAnsiCodePage 変数に設定されたコードページ (デフォルトでは規定のコードページ) が使われます。
MecsShrinkElement 関数は文字コード変換を伴わずに WideString を AnsiString に変換します。
分野の指定
AnsiString ルーチン
Unicode 版 Delphi の構文:
function MecsShrinkElement(const S: WideString): RawByteString;
ANSI 版 Delphi の構文:
function MecsShrinkElement(const S: WideString): AnsiString;
説明:
MecsShrinkElement 関数は文字コード変換を伴わずに WideString を AnsiString に変換します。
バイト列のバッファとして String (UnicodeString) を利用している場合、バイト列をワード列に単純変換したものが関数の戻り値等で返ってくる場合があります。これを AnsiString の変数に代入してしまうと、暗黙の文字コード変換が起こり文字化けを起こしてしまいます。MecsShrinkElement は暗黙の文字コード変換を回避します。
MecsStretchElement 関数は文字コード変換を伴わずに AnsiString を WideString に変換します。
分野の指定
AnsiString ルーチン
Unicode 版 Delphi の構文:
function MecsStretchElement(const S: RawByteString): WideString;
ANSI 版 Delphi の構文:
function MecsStretchElement(const S: AnsiString): WideString;
説明:
MecsStretchElement 関数は文字コード変換を伴わずに AnsiString を WideString に変換します。
バイト列のバッファとして String (UnicodeString) を利用している場合、バイト列をワード列に単純変換したものを関数の引数等に指定しなければならない場合があります。これに AnsiString の変数を代入してしまうと、暗黙の文字コード変換が起こり文字化けを起こしてしまいます。MecsStretchElement は暗黙の文字コード変換を回避します。
MecsEastAsianWidth 関数は東アジアの文字幅を取得します。
分野の指定
UnicodeString / WideString ルーチン
Delphi の構文:
function MecsEastAsianWidth(U: UCS4Char): TEastAsianWidth;
説明:
MecsEastAsianWidth 関数は東アジアの文字幅を取得します。U に指定した Unicode コードポイントで表される文字の文字幅を取得します。戻り値は以下のようになります。
eawNeutral |
ニュートラル。東アジアの文字列には通常含まれない。 全角サイズでも半角サイズでもない。 |
eawFullwidth |
いわゆる全角文字。 |
eawHalfwidth |
いわゆる半角文字。 |
eawWide |
これもいわゆる全角文字。 |
eawNarrow |
これもいわゆる半角文字。 |
eawAmbiguous |
曖昧。東アジアではこの属性の文字は通常、いわゆる全角文字として扱う。 その他の地域ではいわゆる半角文字として扱う。 |
東アジアに於いては eawFullwidth / eawWide / eawAmbiguous 属性を持つ Unicode 文字はいわゆる全角文字として扱う必要があります。マルチバイト Ansi で言う所の全角と半角を判断するには MecsIsFullWidth 関数を利用します。
関連情報:
MecsIsNormalized 関数は Unicode 文字列の標準化 (正規化) 種類を判定します。
分野の指定
UnicodeString / WideString ルーチン
Delphi の構文:
function MecsIsNormalized(const AText: WideString; NormForm: TNORM_FORM): Boolean;
説明:
MecsIsNormalized 関数は Unicode 文字列の標準化 (正規化) 種類を判定します。AText に指定された Unicode 文字列が標準化 (正規化) されていれば True , されていなければ False を返します。標準化 (正規化) されている場合には NormForm に標準化 (正規化) の種類が返ります。標準化 (正規化) の種類については以下を参照してください。
NormalizationOther |
その他の標準化 (正規化) 方法。 |
NormalizationC |
Normalization Form Canonical Composition (NFC) |
NormalizationD |
Normalization Form Canonical Decomposition (NFD) |
NormalizationKC |
Normalization Form Compatibility Composition (NFKC) |
NormalizationKD |
Normalization Form Compatibility Decomposition (NFKD) |
注意:
MecsIsNormalize 関数を利用する場合、XP / Serever 2003 では"Microsoft Internationalized Domain Names (IDN) Mitigation APIs 1.1" または Internet Explorer 7.0 以上が必要となります。Vista 以降の OS で特に必要とするものはありません。
関連情報:
いわゆる "全角チルダ / 波ダッシュ問題" を引き起こす文字をインポート用に再マッピングします。
分野の指定
UnicodeString / WideString ルーチン
Unicode 版 Delphi の構文:
function MecsMappingFix_CP932ToUnicode(const S: UnicodeString): UnicodeString;
function MecsMappingFix_CP932ToUnicode(const S: WideString): WideString;
ANSI 版 Delphi の構文:
function MecsMappingFix_CP932ToUnicode(const S: WideString): WideString;
説明:
MecsMappingFix_CP932ToUnicode 関数はいわゆる "全角チルダ / 波ダッシュ問題" を引き起こす文字をインポート用に再マッピングします。S に指定された Unicode 文字列に含まれる、"ANSI -> Unicode 変換後に CP932 非互換となる文字" を "変換後に CP932 互換となる文字" へ再マッピングします。
― (1-17:0x8150) |
— (U+2014: EM DASH) |
― (U+2015: HORIZONTAL BAR) |
 ̄ (1-29:0x815C) |
‾ (U+203E: OVERLINE) |
 ̄ (U+FFE3: FULLWIDTH MACRON) |
CP932 (Shift-JIS) から UnicodeString / WideString にコンバートした後にこの関数を通して、変換された文字列が CP932 (Shift-JIS) 収録文字のみで構成されるように再マッピングする事が可能です。
// Unicode 版 Delphi での例
// (SJIS.TXT は Shift-JIS のファイル)
var
SL: TStringList;
Enc: TEncoding;
begin
SL := TstringList.Create;
Enc := TEncoding.GetEncoding(932);
try
SL.LoadFromFile('C:\SJIS.TXT', Enc);
ShowMessage(SL.Text); // CP932 非互換文字へマッピングされる
SL.Text := MecsMappingFix_CP932ToUnicode(SL.Text);
ShowMessage(SL.Text); // CP932 互換文字へマッピングされる
finally
Enc.Free;
SL.Free;
end;
end;
|
関連情報:
新常用漢字のうち、JIS X 0208 に存在しない文字を再マッピングします。
分野の指定
UnicodeString / WideString ルーチン
Unicode 版 Delphi の構文:
function MecsMappingFix_JISX0208ToJISX0213(const S: UnicodeString): UnicodeString;
function MecsMappingFix_JISX0208ToJISX0213(const S: WideString): WideString;
ANSI 版 Delphi の構文:
function MecsMappingFix_JISX0208ToJISX0213(const S: WideString): WideString;
説明:
MecsMappingFix_JISX0208ToJISX0213 関数は新常用漢字のうち、JIS X 0208 に存在しない文字を再マッピングします。
剥 (U+5265) |
剝 (U+525D) |
填 (U+586B) |
塡 (U+5861) |
頬 (U+982C) |
頰 (U+9830) |
叱 (U+53F1) |
𠮟 (U+20B9F) |
関連情報:
いわゆる "全角チルダ / 波ダッシュ問題" を引き起こす文字をインポート用に再マッピングします。
分野の指定
UnicodeString / WideString ルーチン
Unicode 版 Delphi の構文:
function MecsMappingFix_JISX0208ToUnicode(const S: UnicodeString): UnicodeString;
function MecsMappingFix_JISX0208ToUnicode(const S: WideString): WideString;
ANSI 版 Delphi の構文:
function MecsMappingFix_JISX0208ToUnicode(const S: WideString): WideString;
説明:
MecsMappingFix_JISX0208ToUnicode 関数はいわゆる "全角チルダ / 波ダッシュ問題" を引き起こす文字をインポート用に再マッピングします。S に指定された Unicode 文字列に含まれる、"ANSI -> Unicode 変換後に JIS X 0208 非互換となる文字" を "変換後に JIS X 0208 互換となる文字" へ再マッピングします。
― (1-17:0x8150) |
— (U+2014: EM DASH) |
― (U+2015: HORIZONTAL BAR) |
 ̄ (1-29:0x815C) |
‾ (U+203E: OVERLINE) |
 ̄ (U+FFE3: FULLWIDTH MACRON) |
∥ (1-34:0x8161) |
‖ (U+2016: DOUBLE VERTICAL LINE) |
∥ (U+2225: PARALLEL TO) |
- (1-61:0x817C) |
− (U+2212: MINUS SIGN) |
- (U+FF0D: FULLWIDTH HYPHEN-MINUS) |
~ (1-33:0x8160) |
〜 (U+301C: WAVE DASH) |
~ (U+FF5E: FULLWIDTH TILDE) |
¢ (1-81:0x8191) |
¢ (U+00A2: CENT SIGN) |
¢ (U+FFE0: FULLWIDTH CENT SIGN) |
£ (1-82:0x8192) |
£ (U+00A3: POUND SIGN) |
£ (U+FFE1: FULLWIDTH POUND SIGN) |
¬ (2-44:0x81CA) |
¬ (U+00AC: NOT SIGN) |
¬ (U+FFE2: FULLWIDTH NOT SIGN) |
JIS-Code (ISO2020-JP) や EUC-JP から UnicodeString / WideString にコンバートした後にこの関数を通して、変換された文字列が JIS X 0208 収録文字のみで構成されるように再マッピングする事が可能です。
MecsMappingFix_UnicodeToJISX0208() の逆を行う関数ですが、"― (1-17:0x8150)" と " ̄ (1-29:0x815C)" に関しては逆変換しない事に注意が必要です。
// Unicode 版 Delphi での例
// (JISX0208.TXT は JisCode のファイル)
var
SL: TStringList;
Enc: TEncoding;
begin
SL := TstringList.Create;
Enc := TEncoding.GetEncoding(50220);
try
SL.LoadFromFile('C:\JISX0208.TXT', Enc);
ShowMessage(SL.Text); // JIS X 0208 非互換文字へマッピングされる
SL.Text := MECSMappingFix_JISX0208ToUnicode(SL.Text);
ShowMessage(SL.Text); // JIS X 0208 互換文字へマッピングされる
finally
Enc.Free;
SL.Free;
end;
end;
|
関連情報:
いわゆる "JIS2004 問題 (新常用漢字問題)" を引き起こす文字を再マッピングします。単独で使う事はありません。
分野の指定
UnicodeString / WideString ルーチン
Unicode 版 Delphi の構文:
function MecsMappingFix_JISX0213ToJISX0208(const S: UnicodeString): UnicodeString;
function MecsMappingFix_JISX0213ToJISX0208(const S: WideString): WideString;
ANSI 版 Delphi の構文:
function MecsMappingFix_JISX0213ToJISX0208(const S: WideString): WideString;
説明:
MecsMappingFix_JISX0213ToJISX0208 関数はいわゆる "JIS2004 問題 (新常用漢字問題)" を引き起こす文字を再マッピングします。S に指定された Unicode 文字列に含まれる、JIS X 0213 常用漢字を JIS X 0208 互換文字へ再マッピングします。
剝 (U+525D) |
剥 (U+5265) |
塡 (U+5861) |
填 (U+586B) |
頰 (U+9830) |
頬 (U+982C) |
𠮟 (U+20B9F) |
叱 (U+53F1) |
これらの文字は新常用漢字であるものの、SHIFT-JIS 等の JIS X 0208 文字集合には含まれていません。JIS X 0208 が改訂される可能性もありますが、現状では不整合が起きてしまいますので、現行の JIS X 0208 に合わせた形で再マッピングを行います。
関連情報:
いわゆる "全角チルダ / 波ダッシュ問題" を引き起こす文字をエクスポート用に再マッピングします。"JIS2004 問題 (新常用漢字問題)" も併せて修正します。
分野の指定
UnicodeString / WideString ルーチン
Unicode 版 Delphi の構文:
function MecsMappingFix_UnicodeToCP932(const S: UnicodeString): UnicodeString;
function MecsMappingFix_UnicodeToCP932(const S: WideString): WideString;
ANSI 版 Delphi の構文:
function MecsMappingFix_UnicodeToCP932(const S: WideString): WideString;
説明:
MecsMappingFix_UnicodeToCP932 関数はいわゆる "全角チルダ / 波ダッシュ問題" を引き起こす文字をエクスポート用に再マッピングします。"JIS2004 問題 (新常用漢字問題)" も併せて修正します。S に指定された文字列に含まれる、"Unicode -> ANSI 変換後に CP932 非互換となる文字" を "変換後に CP932 互換となる文字" へ再マッピングします。
‑ (U+2011: NON-BREAKING HYPHEN) |
- (U+002D: HYPHEN-MINUS) |
- (ASCII: 0x2D) |
‒ (U+2012: FIGURE DASH) |
– (U+2013: EN DASH) |
— (U+2014: EM DASH) |
― (U+2015: HORIZONTAL BAR) |
― (1-17:0x8150) |
‾ (U+203E: OVERLINE) |
 ̄ (U+FFE3: FULLWIDTH MACRON) |
 ̄ (1-29:0x815C) |
− (U+2212: MINUS SIGN) |
- (U+FF0D: FULLWIDTH HYPHEN-MINUS) |
- (1-61:0x817C) |
﹘ (U+FE58: SMALL EM DASH) |
﹣ (U+FE63: SMALL HYPHEN-MINUS) |
UnicodeString / WideString を CP932 (Shift-JIS) にコンバートする前にこの関数を通して、変換する文字列が文字化けしないように再マッピングする事が可能です。内部で、MecsMappingFix_JISX0213ToJISX0208() も呼ばれており、"JIS2004 問題 (新常用漢字問題)" も併せて解決します。
// Unicode 版 Delphi での例
var
SL: TStringList;
Enc: TEncoding;
S: UnicodeString;
begin
SL := TstringList.Create;
Enc := TEncoding.GetEncoding(932);
try
S := #$2014#$203E#$525D#$5861#$9830#$20B9F;
SL.Text := S;
SL.SaveToFile('C:\UNICODE1.TXT', Enc); // 文字化けする
SL.Text := MecsMappingFix_UnicodeToCP932(S);
SL.SaveToFile('C:\UNICODE2.TXT', Enc); // 文字化けしない
finally
Enc.Free;
SL.Free;
end;
end; |
関連情報:
いわゆる "全角チルダ / 波ダッシュ問題" を引き起こす文字をエクスポート用に再マッピングします。"JIS2004 問題 (新常用漢字問題)" も併せて修正します。
<!> この関数は以前、MECSMappingFixJA() という名称でリリースされていました <!>
分野の指定
UnicodeString / WideString ルーチン
Unicode 版 Delphi の構文:
function MecsMappingFix_UnicodeToJISX0208(const S: UnicodeString): UnicodeString;
function MecsMappingFix_UnicodeToJISX0208(const S: WideString): WideString;
ANSI 版 Delphi の構文:
function MecsMappingFix_UnicodeToJISX0208(const S: WideString): WideString;
説明:
MecsMappingFix_UnicodeToJISX0208 関数はいわゆる "全角チルダ / 波ダッシュ問題" を引き起こす文字をエクスポート用に再マッピングします。"JIS2004 問題 (新常用漢字問題)" も併せて修正します。S に指定された文字列に含まれる、"Unicode -> ANSI 変換後に JIS X 0208 非互換となる文字" を "変換後に JIS X 0208 互換となる文字" へ再マッピングします。
‑ (U+2011: NON-BREAKING HYPHEN) |
- (U+002D: HYPHEN-MINUS) |
- (ASCII: 0x2D) |
‒ (U+2012: FIGURE DASH) |
– (U+2013: EN DASH) |
— (U+2014: EM DASH) |
― (U+2015: HORIZONTAL BAR) |
― (1-17:0x8150) |
‾ (U+203E: OVERLINE) |
 ̄ (U+FFE3: FULLWIDTH MACRON) |
 ̄ (1-29:0x815C) |
∥ (U+2225: PARALLEL TO) |
‖ (U+2016: DOUBLE VERTICAL LINE) |
∥ (1-34:0x8161) |
﹘ (U+FE58: SMALL EM DASH) |
− (U+2212: MINUS SIGN) |
- (1-61:0x817C) |
﹣ (U+FE63: SMALL HYPHEN-MINUS) |
- (U+FF0D: FULLWIDTH HYPHEN-MINUS) |
~ (U+FF5E: FULLWIDTH TILDE) |
〜 (U+301C: WAVE DASH) |
~ (1-33:0x8160) |
¢ (U+FFE0: FULLWIDTH CENT SIGN) |
¢ (U+00A2: CENT SIGN) |
¢ (1-81:0x8191) |
£ (U+FFE1: FULLWIDTH POUND SIGN) |
£ (U+00A3: POUND SIGN) |
£ (1-82:0x8192) |
¬ (U+FFE2: FULLWIDTH NOT SIGN) |
¬ (U+00AC: NOT SIGN) |
¬ (2-44:0x81CA) |
UnicodeString / WideString を JIS-Code (ISO2020-JP) や EUC-JP にコンバートする前にこの関数を通して、変換する文字列が文字化けしないように再マッピングする事が可能です。内部で、MecsMappingFix_JISX0213ToJISX0208() も呼ばれており、"JIS2004 問題 (新常用漢字問題)" も併せて解決します。
// Unicode 版 Delphi での例
var
SL: TStringList;
Enc: TEncoding;
S: UnicodeString;
begin
SL := TstringList.Create;
Enc := TEncoding.GetEncoding(50220);
try
S := #$2014#$203E#$2225#$FF0D#$FF5E#$FFE0#$FFE1#$FFE2#$525D#$5861#$9830#$20B9F;
SL.Text := S;
SL.SaveToFile('C:\UNICODE1.TXT', Enc); // 文字化けする
SL.Text := MECSMappingFix_UnicodeToJISX0208(S);
SL.SaveToFile('C:\UNICODE2.TXT', Enc); // 文字化けしない
finally
Enc.Free;
SL.Free;
end;
end; |
関連情報:
MecsNormalize 関数は Unicode 文字列を標準化 (正規化) します。
分野の指定
UnicodeString / WideString ルーチン
Delphi の構文:
function MecsNormalize(const Src: WideString; var Dst: WideString; NormForm: TNORM_FORM): Boolean;
説明:
MecsNormalize 関数は Unicode 文字列を標準化 (正規化) します。Src に指定された Unicode 文字列を NormForm で指定した方法で標準化 (正規化) し、Dst に格納します。標準化 (正規化) に成功した場合には戻り値に True , 失敗した場合には False が返ります。標準化 (正規化) の種類については以下を参照してください。
NormalizationOther |
その他の標準化 (正規化) 方法。 |
NormalizationC |
Normalization Form Canonical Composition (NFC) |
NormalizationD |
Normalization Form Canonical Decomposition (NFD) |
NormalizationKC |
Normalization Form Compatibility Composition (NFKC) |
NormalizationKD |
Normalization Form Compatibility Decomposition (NFKD) |
注意:
MecsNormalize 関数を利用する場合、
上記条件に該当しない場合で、OS が NT 3.1 以降の場合には代替手段を使って標準化 (正規化) が行われます。
Unicode には 結合文字列 / 合成文字 の問題があるため、文字列の比較や検索には標準化 (正規化) を前処理として行わなくてはならない場合があります。詳しくは関連情報をご覧下さい。
関連情報:
MecsStringWidth 関数は文字列から文字幅を得ます。
分野の指定
UnicodeString / WideString ルーチン
Unicode 版 Delphi の構文:
function MecsStringWidth(const S: UnicodeString; EAW: Boolean = True): Integer;
function MecsStringWidth(const S: WideString; EAW: Boolean = True): Integer;
ANSI 版 Delphi の構文:
function MecsStringWidth(const S: WideString; EAW: Boolean = True): Integer;
説明:
MecsStringWidth 関数は文字列から文字幅を得ます。半角サイズの文字は 1 , 全角サイズの文字は 2 でカウントされます。Ansi アプリケーションを Unicode アプリケーションにマイグレーションしたい場合、ソースコード中で文字列の幅を Length() で取得しているコードを MecsStringWidth() で置換する事で不具合を回避できます。EAW に True を設定すると東アジアの文字幅が考慮されます。
関連情報:
StrLen 関数は文字列内のヌルターミネータを除いた文字構成要素数を返します。
分野の指定
UnicodeString / WideString ルーチン
ANSI 版 Delphi の構文:
function StrLen(const Str: PWideChar): Cardinal;
説明:
StrLen 関数は文字列内のヌルターミネータを除いた文字構成要素数を返します。
Unicode 版 Delphi には SysUtils 名前空間に PWideChar 用の StrLen 関数が存在するのですが、ANSI 版 Delphi には存在しません。この差異を補うための ANSI 版 Delphi 専用関数となっています。
関連情報:
StrPos 関数は,Str1 内の最初の Str2 を指すポインタを返します。
分野の指定
UnicodeString / WideString ルーチン
ANSI 版 Delphi の構文:
function StrPos(const Str1, Str2: PWideChar): PWideChar;
説明:
StrPos 関数は Str1 内の最初の Str2 を指すポインタを返します。Str2 が Str1 にない場合,StrPos は nil を返します。
Unicode 版 Delphi には SysUtils 名前空間に PWideChar 用の StrPos 関数が存在するのですが、ANSI 版 Delphi には存在しません。この差異を補うための ANSI 版 Delphi 専用関数となっています。
関連情報:
MecsAnsiPos 関数は指定された部分文字列の開始位置のインデックスを返します。
分野の指定
Common ルーチン
Unicode 版 Delphi の構文:
function MecsAnsiPos(const SubStr, S: RawByteString; CodePage: DWORD = 0): Integer;
function MecsAnsiPos(const SubStr, S: UnicodeString): Integer;
function MecsAnsiPos(const SubStr, S: WideString): Integer;
ANSI 版 Delphi の構文:
function MecsAnsiPos(const SubStr, S: AnsiString; CodePage: DWORD = 0): Integer;
function MecsAnsiPos(const SubStr, S: WideString): Integer;
説明:
MecsAnsiPos 関数は指定された部分文字列の開始位置のインデックスを返します。Substr パラメータが文字列 S にあるときにそのエレメントオフセットを取得できます。Substr が S にない場合,MecsAnsiPos は 0 を返します。
AnsiString 版関数に CodePage を指定することで、コードページを強制する事ができます。コードページを指定しなかった場合には、Unicode 版 Delphi の場合には AnsiString のコードページ、ANSI 版 Delphi の場合には MECSUtils.DefaultAnsiCodePage 変数に設定されたコードページ (デフォルトでは規定のコードページ) が使われます。
RTL の AnsiPos に相当する機能です。
MecsAnsiPosEx 関数は文字列内で最初に出現する部分文字列のインデックスを返します。
分野の指定
Common ルーチン
Unicode 版 Delphi の構文:
function MecsAnsiPosEx(const SubStr, S: RawByteString; Offset: Integer = 1; CodePage: DWORD = 0): Integer;
function MecsAnsiPosEx(const SubStr, S: UnicodeString Offset: Integer = 1): Integer;
function MecsAnsiPosEx(const SubStr, S: WideString Offset: Integer = 1): Integer;
ANSI 版 Delphi の構文:
function MecsAnsiPosEx(const SubStr, S: AnsiString; Offset: Integer = 1; CodePage: DWORD = 0): Integer;
function MecsAnsiPosEx(const SubStr, S: WideString Offset: Integer = 1): Integer;
説明:
MecsAnsiPosEx 関数は文字列内で最初に出現する部分文字列のインデックスを返します。MecsAnsiPosEx は、Offset の位置から検索を開始して、S 内の SubStr のインデックスを返します。Offset が 1 の場合(デフォルト)、MecsAnsiPosEx は MecsAnsiPos と同じになります。
SubStr が見つからない、または Offset が不正な値である(S の長さより大きい、または 1 より小さい)場合、結果は 0 になります。
AnsiString 版関数に CodePage を指定することで、コードページを強制する事ができます。コードページを指定しなかった場合には、Unicode 版 Delphi の場合には AnsiString のコードページ、ANSI 版 Delphi の場合には MECSUtils.DefaultAnsiCodePage 変数に設定されたコードページ (デフォルトでは規定のコードページ) が使われます。
RTL の PosEx はマルチバイト文字に対応していませんが、こちらの AnsiString 版はマルチバイト文字に対応しています。
MecsAnsiStrPos 関数は Str1 内の最初の Str2 を指すポインタを返します。
分野の指定
Common ルーチン
Delphi の構文:
function MecsAnsiStrPos(Str, SubStr: PAnsiChar; CodePage: DWORD = 0): PAnsiChar;
function MecsAnsiStrPos(Str, SubStr: PWideChar): PWideChar;
説明:
MecsAnsiStrPos 関数は Str1 内の最初の Str2 を指すポインタを返します。AnsiStrPos 関数を呼び出すと,Str における最初の SubStr の位置がわかります。SubStr が Str にない場合,AnsiStrPos は nil を返します。
AnsiString 版関数に CodePage を指定することで、コードページを強制する事ができます。コードページを指定しなかった場合には、Unicode 版 Delphi の場合には AnsiString のコードページ、ANSI 版 Delphi の場合には MECSUtils.DefaultAnsiCodePage 変数に設定されたコードページ (デフォルトでは規定のコードページ) が使われます。
RTL の AnsiStrPos に相当する機能です。
MecsCharLength 関数は文字で使われるエレメント数を返します。
分野の指定
Common ルーチン
Unicode 版 Delphi の構文:
function MecsCharLength(const S: RawByteString; Index: Integer; CodePage: DWORD = 0): Integer;
function MecsCharLength(const S: UnicodeString; Index: Integer): Integer;
function MecsCharLength(const S: WideString; Index: Integer): Integer;
ANSI 版 Delphi の構文:
function MecsCharLength(const S: AnsiString; Index: Integer; CodePage: DWORD = 0): Integer;
function MecsCharLength(const S: WideString; Index: Integer): Integer;
説明:
MecsCharLength 関数を呼び出すと、S の Index 位置にある文字のサイズがエレメント単位でわかります。エレメントは文字を構成する要素で、AnsiString なら AnsiChar、UnicodeString / WideString なら WideChar となります。
AnsiString 版関数に CodePage を指定することで、コードページを強制する事ができます。コードページを指定しなかった場合には、Unicode 版 Delphi の場合には AnsiString のコードページ、ANSI 版 Delphi の場合には MECSUtils.DefaultAnsiCodePage 変数に設定されたコードページ (デフォルトでは規定のコードページ) が使われます。
RTL の CharLength に相当する機能です。
サンプルコード:
AnsiString(CP932)
1 |
2 |
3 |
4 |
5 |
6 |
7 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
A |
B |
あ |
い |
う |
C |
D |
0x41 |
0x42 |
0x82 |
0xA0 |
0x82 |
0xA2 |
0x82 |
0xA4 |
0x43 |
0x44 |
// Unicode 版 Delphi での例
type
SJISString = type AnsiString(932);
var
A: SJISString;
Idx: Integer;
begin
A := 'ABあいうCD';
// CharLength の引数 Index は文字インデックスではなくエレメントインデックス
Idx := CharLength(A, 3); // 2
ShowMessage(IntToStr(Idx));
Idx := CharLength(A, 4); // 1
ShowMessage(IntToStr(Idx));
Idx := MecsCharLength(A, 3); // 2
ShowMessage(IntToStr(Idx));
Idx := MecsCharLength(A, 4); // 2
ShowMessage(IntToStr(Idx));
end;
|
// ANSI / Unicode 版 共通の例
var
A: AnsiString;
Idx: Integer;
begin
A := 'ABあいうCD';
// CharLength の引数 Index は文字インデックスではなくエレメントインデックス
Idx := CharLength(A, 3);   // 2
ShowMessage(IntToStr(Idx));
Idx := CharLength(A, 4); // 1
ShowMessage(IntToStr(Idx));
Idx := MecsCharLength(A, 3, 932); // 2
ShowMessage(IntToStr(Idx));
Idx := MecsCharLength(A, 4, 932); // 2
ShowMessage(IntToStr(Idx));
end;
|
UnicodeString / WideString
1 |
2 |
3 |
4 |
5 |
6 |
7 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
A |
B |
𠮷 |
野 |
屋 |
C |
D |
0x0041 |
0x0042 |
0xD842 |
0xDFB7 |
0x91CE |
0x5C4B |
0x0043 |
0x0044 |
// Unicode 版 Delphi での例
var
U: UnicodeString;
Idx: Integer;
begin
U := 'AB' + #$20BB7 + '野屋CD';
// CharLength の引数 Index は文字インデックスではなくエレメントインデックス
Idx := CharLength(U, 3); // 4 (エレメント単位ではなくバイト単位)
ShowMessage(IntToStr(Idx));
Idx := CharLength(U, 4); // 2 (エレメント単位ではなくバイト単位)
ShowMessage(IntToStr(Idx));
Idx := MecsCharLength(U, 3); // 2
ShowMessage(IntToStr(Idx));
Idx := MecsCharLength(U, 4); // 1
ShowMessage(IntToStr(Idx));
end;
|
// ANSI / Unicode 版 共通の例
var
W: WideString;
Idx: Integer;
begin
W := 'AB' + #$D842#$DFB7 + '野屋CD';
Idx := MecsCharLength(W, 3); // 2
ShowMessage(IntToStr(Idx));
Idx := MecsCharLength(W, 4); // 1
ShowMessage(IntToStr(Idx));
end;
|
UTF8String(CP_UTF8/CP65001)
1 |
2 |
3 |
4 |
5 |
6 |
7 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
A |
B |
𠮷 |
野 |
屋 |
C |
D |
0x41 |
0x42 |
0xF0 |
0xA0 |
0xAE |
0xB7 |
0xE9 |
0x87 |
0x8E |
0xE5 |
0xB1 |
0x8B |
0x43 |
0x44 |
// Unicode 版 Delphi での例
var
U8: UTF8String;
Idx: Integer;
begin
U8 := 'AB' + #$20BB7 + '野屋CD';
// CharLength の引数 Index は文字インデックスではなくエレメントインデックス
Idx := AnsiStrings.CharLength(U8, 3); // 1 (NG)
ShowMessage(IntToStr(Idx));
Idx := AnsiStrings.CharLength(U8, 4); // 1 (NG)
ShowMessage(IntToStr(Idx));
Idx := MecsCharLength(U8, 3); // 4
ShowMessage(IntToStr(Idx));
Idx := MecsCharLength(U8, 4); // 3
ShowMessage(IntToStr(Idx));
end;
|
// ANSI 版 Delphi での例
var
U8: UTF8String;
Idx: Integer;
begin
U8 := 'AB' + #$20BB7 + '野屋CD';
// CharLength の引数 Index は文字インデックスではなくエレメントインデックス
Idx := CharLength(U8, 3); // 1 (NG)
ShowMessage(IntToStr(Idx));
Idx := CharLength(U8, 4); // 1 (NG)
ShowMessage(IntToStr(Idx));
Idx := MecsCharLength(U8, 3); // 4
ShowMessage(IntToStr(Idx));
Idx := MecsCharLength(U8, 4); // 3
ShowMessage(IntToStr(Idx));
end;
|
RTL の CharLength は不思議な仕様になっています。まず、Unicode 版はエレメント数ではなく何故かバイト数を返します (ヘルプを読む限りではこれが正しい動作のようですが、エレメント数を返す関数がありません)。更に言えば、Unicode 版 Delphi では CharLength (AnsiString 版) が AnsiStrings 名前空間と SysUtils 名前空間に重複して存在します (オーバーロードされたものではありません)。
そのため、AnsiStrings を uses していると"E2251 'CharLength' へのオーバーロード呼び出しはあいまいです"が発生してしまいます。このような場合には、"AnsiStrings.CharLength"のように名前空間を明示する必要があります。
CharLength でエレメント単位の長さを知りたい場合には以下のようにします。
// Unicode 版 Delphi での例
var
U: UnicodeString;
Idx: Integer;
begin
U := 'AB' + #$20BB7 + '野屋CD';
// CharLength の引数 Index は文字インデックスではなくエレメントインデックス
Idx := CharLength(U, 3) div StringElementSize(U); // 2 (エレメント単位)
ShowMessage(IntToStr(Idx));
Idx := CharLength(U, 4) div StringElementSize(U); // 1 (エレメント単位)
ShowMessage(IntToStr(Idx));
end;
|
逆に MecsCharLength でバイト単位の長さを知りたい場合には以下のようにします。
// Unicode 版 Delphi での例
var
U: UnicodeString;
Idx: Integer;
begin
U := 'AB' + #$20BB7 + '野屋CD';
Idx := MecsCharLength(U, 3) * StringElementSize(U); // 4 (バイト単位)
ShowMessage(IntToStr(Idx));
Idx := MecsCharLength(U, 4) * StringElementSize(U); // 2 (バイト単位)
ShowMessage(IntToStr(Idx));
end;
|
MecsCharToElementIndex 関数は文字列内の指定された文字の最初のエレメントを 1 から始まるインデックスで返します。
分野の指定
Common ルーチン
Unicode 版 Delphi の構文:
function MecsCharToElementIndex(const S: RawByteString; Index: Integer; CodePage: DWORD = 0): Integer;
function MecsCharToElementIndex(const S: UnicodeString; Index: Integer): Integer;
function MecsCharToElementIndex(const S: WideString; Index: Integer): Integer;
ANSI 版 Delphi の構文:
function MecsCharToElementIndex(const S: AnsiString; Index: Integer; CodePage: DWORD = 0): Integer;
function MecsCharToElementIndex(const S: WideString; Index: Integer): Integer;
説明:
MecsCharToElementIndex 関数を呼び出すと、文字列 S の指定された位置にある文字のエレメントオフセットを取得できます。1 は最初の文字、2 は 2 番目の文字を指定します。
MecsCharToElementIndex は、Index が範囲外の場合 (Index <= 0 または S の文字数が Index より小さい) にゼロを返します。Index パラメータが UTF-16 のサロゲートペア や 結合文字 を示す場合、
MecsCharToElementIndex は最初のエレメントのオフセットを返します。
端的に言えば、MecsCharToElementIndex は文字インデックスから、文字の先頭に位置するエレメントのインデックスを取得する関数です。
AnsiString 版関数に CodePage を指定することで、コードページを強制する事ができます。コードページを指定しなかった場合には、Unicode 版 Delphi の場合には AnsiString のコードページ、ANSI 版 Delphi の場合には MECSUtils.DefaultAnsiCodePage 変数に設定されたコードページ (デフォルトでは規定のコードページ) が使われます。
RTL の CharToByteIndex / CharToElementIndex (Unicode 版 Delphi) に相当する機能です。
サンプルコード:
AnsiString(CP932)
1 |
2 |
3 |
4 |
5 |
6 |
7 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
A |
B |
あ |
い |
う |
C |
D |
0x41 |
0x42 |
0x82 |
0xA0 |
0x82 |
0xA2 |
0x82 |
0xA4 |
0x43 |
0x44 |
// Unicode 版 Delphi での例
type
SJISString = type AnsiString(932);
var
A: SJISString;
Idx: Integer;
begin
A := 'ABあいうCD';
Idx := CharToElementIndex(A, 3); // 3
ShowMessage(IntToStr(Idx));
Idx := CharToElementIndex(A, 4); // 5
ShowMessage(IntToStr(Idx));
Idx := MecsCharToElementIndex(A, 3); // 3
ShowMessage(IntToStr(Idx));
Idx := MecsCharToElementIndex(A, 4); // 5
ShowMessage(IntToStr(Idx));
end;
|
// ANSI / Unicode 版 共通の例
var
A: AnsiString;
Idx: Integer;
begin
A := 'ABあいうCD';
Idx := CharToByteIndex(A, 3); // 3
ShowMessage(IntToStr(Idx));
Idx := CharToByteIndex(A, 4); // 5
ShowMessage(IntToStr(Idx));
Idx := MecsCharToElementIndex(A, 3, 932); // 3
ShowMessage(IntToStr(Idx));
Idx := MecsCharToElementIndex(A, 4, 932); // 5
ShowMessage(IntToStr(Idx));
end;
|
UnicodeString / WideString
1 |
2 |
3 |
4 |
5 |
6 |
7 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
A |
B |
𠮷 |
野 |
屋 |
C |
D |
0x0041 |
0x0042 |
0xD842 |
0xDFB7 |
0x91CE |
0x5C4B |
0x0043 |
0x0044 |
// Unicode 版 Delphi での例
var
U: UnicodeString;
Idx: Integer;
begin
U := 'AB' + #$20BB7 + '野屋CD';
Idx := CharToElementIndex(U, 3); // 3
ShowMessage(IntToStr(Idx));
Idx := CharToElementIndex(U, 4); // 5
ShowMessage(IntToStr(Idx));
Idx := MecsCharToElementIndex(U, 3); // 3
ShowMessage(IntToStr(Idx));
Idx := MecsCharToElementIndex(U, 4); // 5
ShowMessage(IntToStr(Idx));
end;
|
// ANSI / Unicode 版 共通の例
var
W: WideString;
Idx: Integer;
begin
W := 'AB' + #$D842#$DFB7 + '野屋CD';
{$IFDEF UNICODE}
Idx := CharToElementIndex(W, 3); // 3
ShowMessage(IntToStr(Idx));
Idx := CharToElementIndex(W, 4); // 5
ShowMessage(IntToStr(Idx));
{$ELSE}
// ANSI 版 Delphi の CharToByteIndex() に WideString 版はない
// ANSI 版 Delphi に CharToElementIndex() はない
{$ENDIF}
Idx := MecsCharToElementIndex(W, 3); // 3
ShowMessage(IntToStr(Idx));
Idx := MecsCharToElementIndex(W, 4); // 5
ShowMessage(IntToStr(Idx));
end;
|
UTF8String(CP_UTF8/CP65001)
1 |
2 |
3 |
4 |
5 |
6 |
7 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
A |
B |
𠮷 |
野 |
屋 |
C |
D |
0x41 |
0x42 |
0xF0 |
0xA0 |
0xAE |
0xB7 |
0xE9 |
0x87 |
0x8E |
0xE5 |
0xB1 |
0x8B |
0x43 |
0x44 |
// Unicode 版 Delphi での例
var
U8: UTF8String;
Idx: Integer;
begin
U8 := 'AB' + #$20BB7 + '野屋CD';
Idx := CharToElementIndex(U8, 3); // 3
ShowMessage(IntToStr(Idx));
Idx := CharToElementIndex(U8, 4); // 4 (NG)
ShowMessage(IntToStr(Idx));
Idx := MecsCharToElementIndex(U8, 3); // 3
ShowMessage(IntToStr(Idx));
Idx := MecsCharToElementIndex(U8, 4); // 7
ShowMessage(IntToStr(Idx));
end;
|
// ANSI 版 Delphi での例
var
U8: UTF8String;
Idx: Integer;
begin
U8 := 'AB' + #$F0#$A0#$AE#$B7 + #$E9#$87#$8E + #$E5#$B1#$8B + 'CD';
Idx := CharToByteIndex(U8, 3); // 3
ShowMessage(IntToStr(Idx));
Idx := CharToByteIndex(U8, 4); // 5 (NG)
ShowMessage(IntToStr(Idx));
Idx := MecsCharToElementIndex(U8, 3, CP_UTF8); // 3
ShowMessage(IntToStr(Idx));
Idx := MecsCharToElementIndex(U8, 4, CP_UTF8); // 7
ShowMessage(IntToStr(Idx));
end;
|
注意:
RTL の CharToElementIndex は特定の条件の場合に不正な値を返します。 - XE3 で修正されています
関連情報:
MecsCharToElementLen 関数は文字列の最初の MaxLen の文字の長さをエレメント数で返します。
分野の指定
Common ルーチン
Unicode 版 Delphi の構文:
function MecsCharToElementLen(const S: RawByteString; MaxLen: Integer; CodePage: DWORD = 0): Integer;
function MecsCharToElementLen(const S: UnicodeString; MaxLen: Integer): Integer;
function MecsCharToElementLen(const S: WideString; MaxLen: Integer): Integer;
ANSI 版 Delphi の構文:
function MecsCharToElementLen(const S: AnsiString; MaxLen: Integer; CodePage: DWORD = 0): Integer;
function MecsCharToElementLen(const S: WideString; MaxLen: Integer): Integer;
説明:
MecsCharToElementLen 関数を呼び出すと、文字列の文字単位の長さをそれに対応するエレメント単位の長さに変換できます。MecsCharToElementLen は、S の最初の MaxLen 数の文字で必要なエレメント数を返します。S が MaxLen より小さい場合、CharToByteLen は S の長さをエレメント数で返します。
端的に言えば、MecsCharToElementLen は文字インデックスから、文字の最後に位置するエレメントのインデックス...つまり、文字単位で考えて"キリのいいエレメント数"を取得する関数です。エレメントを文字単位で区切って処理する際に利用します。
AnsiString 版関数に CodePage を指定することで、コードページを強制する事ができます。コードページを指定しなかった場合には、Unicode 版 Delphi の場合には AnsiString のコードページ、ANSI 版 Delphi の場合には MECSUtils.DefaultAnsiCodePage 変数に設定されたコードページ (デフォルトでは規定のコードページ) が使われます。
RTL の CharToByteLen / CharToElementLen (Unicode 版 Delphi) に相当する機能です。
サンプルコード:
AnsiString(CP932)
1 |
2 |
3 |
4 |
5 |
6 |
7 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
A |
B |
あ |
い |
う |
C |
D |
0x41 |
0x42 |
0x82 |
0xA0 |
0x82 |
0xA2 |
0x82 |
0xA4 |
0x43 |
0x44 |
// Unicode 版 Delphi での例
type
SJISString = type AnsiString(932);
var
A: SJISString;
Idx: Integer;
begin
A := 'ABあいうCD';
Idx := CharToElementLen(A, 3); // 4
ShowMessage(IntToStr(Idx));
Idx := CharToElementLen(A, 4); // 6
ShowMessage(IntToStr(Idx));
Idx := MecsCharToElementLen(A, 3); // 4
ShowMessage(IntToStr(Idx));
Idx := MecsCharToElementLen(A, 4); // 6
ShowMessage(IntToStr(Idx));
end;
|
// ANSI / Unicode 版 共通の例
var
A: AnsiString;
Idx: Integer;
begin
A := 'ABあいうCD';
Idx := CharToByteLen(A, 3); // 4
ShowMessage(IntToStr(Idx));
Idx := CharToByteLen(A, 4); // 6
ShowMessage(IntToStr(Idx));
Idx := MecsCharToElementLen(A, 3, 932); // 4
ShowMessage(IntToStr(Idx));
Idx := MecsCharToElementLen(A, 4, 932); // 6
ShowMessage(IntToStr(Idx));
end;
|
UnicodeString / WideString
1 |
2 |
3 |
4 |
5 |
6 |
7 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
A |
B |
𠮷 |
野 |
屋 |
C |
D |
0x0041 |
0x0042 |
0xD842 |
0xDFB7 |
0x91CE |
0x5C4B |
0x0043 |
0x0044 |
// Unicode 版 Delphi での例
var
U: UnicodeString;
Idx: Integer;
begin
U := 'AB' + #$20BB7 + '野屋CD';
Idx := CharToElementLen(U, 3); // 4
ShowMessage(IntToStr(Idx));
Idx := CharToElementLen(U, 4); // 5
ShowMessage(IntToStr(Idx));
Idx := MecsCharToElementLen(U, 3); // 4
ShowMessage(IntToStr(Idx));
Idx := MecsCharToElementLen(U, 4); // 5
ShowMessage(IntToStr(Idx));
end;
|
// ANSI / Unicode 版 共通の例
var
W: WideString;
Idx: Integer;
begin
W := 'AB' + #$D842#$DFB7 + '野屋CD';
{$IFDEF UNICODE}
Idx := CharToElementLen(W, 3); // 4
ShowMessage(IntToStr(Idx));
Idx := CharToElementLen(W, 4); // 5
ShowMessage(IntToStr(Idx));
{$ELSE}
// ANSI 版 Delphi の CharToByteLen() に WideString 版はない
// ANSI 版 Delphi に CharToElementLen() はない
{$ENDIF}
Idx := MecsCharToElementLen(W, 3); // 4
ShowMessage(IntToStr(Idx));
Idx := MecsCharToElementLen(W, 4); // 5
ShowMessage(IntToStr(Idx));
end;
|
UTF8String(CP_UTF8/CP65001)
1 |
2 |
3 |
4 |
5 |
6 |
7 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
A |
B |
𠮷 |
野 |
屋 |
C |
D |
0x41 |
0x42 |
0xF0 |
0xA0 |
0xAE |
0xB7 |
0xE9 |
0x87 |
0x8E |
0xE5 |
0xB1 |
0x8B |
0x43 |
0x44 |
// Unicode 版 Delphi での例
var
U8: UTF8String;
Idx: Integer;
begin
U8 := 'AB' + #$20BB7 + '野屋CD';
Idx := CharToElementLen(U8, 3); // 3 (NG)
ShowMessage(IntToStr(Idx));
Idx := CharToElementLen(U8, 4); // 4 (NG)
ShowMessage(IntToStr(Idx));
Idx := MecsCharToElementLen(U8, 3); // 6
ShowMessage(IntToStr(Idx));
Idx := MecsCharToElementLen(U8, 4); // 9
ShowMessage(IntToStr(Idx));
end;
|
// ANSI 版 Delphi での例
var
U8: UTF8String;
Idx: Integer;
begin
U8 := 'AB' + #$F0#$A0#$AE#$B7 + #$E9#$87#$8E + #$E5#$B1#$8B + 'CD';
Idx := CharToByteLen(U8, 3); // 4 (NG)
ShowMessage(IntToStr(Idx));
Idx := CharToByteLen(U8, 4); // 5 (NG)
ShowMessage(IntToStr(Idx));
Idx := MecsCharToElementLen(U8, 3, CP_UTF8); // 6
ShowMessage(IntToStr(Idx));
Idx := MecsCharToElementLen(U8, 4, CP_UTF8); // 9
ShowMessage(IntToStr(Idx));
end;
|
MecsCopy 関数は文字列の部分文字列を返します。
分野の指定
Common ルーチン
Unicode 版 Delphi の構文:
function MecsCopy(const S: RawByteString; Index, Count: Integer; CodePage: DWORD = 0): RawByteString;
function MecsCopy(const S: UnicodeString; Index, Count: Integer): UnicodeString;
function MecsCopy(const S: WideString; Index, Count: Integer): WideString;
ANSI 版 Delphi の構文:
function MecsCopy(const S: AnsiString; Index, Count: Integer; CodePage: DWORD = 0): AnsiString;
function MecsCopy(const S: WideString; Index, Count: Integer): WideString;
説明:
MecsCopy 関数は文字列の部分文字列を返します。S は、文字列型の式です。Index と Count は整数型の式です。MecsCopy 関数は、S の Index 文字目から Count 個の文字の入った部分文字列を返します。
Index が S より長い場合、MecsCopy は空の文字列を返します。
コピーできる文字より多い値が Count に指定されている場合、S の Index 文字目 から S の終わりまでの文字が返されます。
AnsiString 版関数に CodePage を指定することで、コードページを強制する事ができます。コードページを指定しなかった場合には、Unicode 版 Delphi の場合には AnsiString のコードページ、ANSI 版 Delphi の場合には MECSUtils.DefaultAnsiCodePage 変数に設定されたコードページ (デフォルトでは規定のコードページ) が使われます。
RTL の Copy に相当する機能ですが、動的配列はサポートしません。また、Index と Count はマルチバイト (AnsiString 版)、サロゲートペア (UnicodeString / WideString 版) を考慮した"文字数"を指定します。
MecsDelete 手続きは文字列から部分文字列を削除します。
分野の指定
Common ルーチン
Unicode 版 Delphi の構文:
procedure MecsDelete(var S: RawByteString; Index, Count: Integer; CodePage: DWORD = 0);
procedure MecsDelete(var S: UnicodeString; Index, Count: Integer);
procedure MecsDelete(var S: WideString; Index, Count: Integer);
ANSI 版 Delphi の構文:
procedure MecsDelete(var S: AnsiString; Index, Count: Integer; CodePage: DWORD = 0);
procedure MecsDelete(var S: WideString; Index, Count: Integer);
説明:
MecsDelete 手続きは、文字列 S の Index 文字目から始まる Count 個の文字の部分文字列を削除します。S は文字列型の変数です。Index と Count は整数型の式です。
index が文字列の長さより大きい場合、または 1 未満の場合は、削除は行われません。
count が index 以降の文字数より大きい場合、MecsDelete は終わりまでのすべての文字を削除します。count が 0 以下の場合は、削除は行われません。
AnsiString 版関数に CodePage を指定することで、コードページを強制する事ができます。コードページを指定しなかった場合には、Unicode 版 Delphi の場合には AnsiString のコードページ、ANSI 版 Delphi の場合には MECSUtils.DefaultAnsiCodePage 変数に設定されたコードページ (デフォルトでは規定のコードページ) が使われます。
RTL の Delete に相当する機能です。Index と Count はマルチバイト (AnsiString 版)、サロゲートペア (UnicodeString / WideString 版) を考慮した"文字数"を指定します。
MecsElementToCharIndex 関数は文字列内の指定されたエレメントを含む文字の位置を返します。
分野の指定
Common ルーチン
Unicode 版 Delphi の構文:
function MecsElementToCharIndex(const S: RawByteString; Index: Integer; CodePage: DWORD = 0): Integer;
function MecsElementToCharIndex(const S: UnicodeString; Index: Integer): Integer;
function MecsElementToCharIndex(const S: WideString; Index: Integer): Integer;
ANSI 版 Delphi の構文:
function MecsElementToCharIndex(const S: AnsiString; Index: Integer; CodePage: DWORD = 0): Integer;
function MecsElementToCharIndex(const S: WideString; Index: Integer): Integer;
説明:
MecsElementToCharIndex 関数を呼び出すと、文字列内で特定のエレメントを含んでいる文字がわかります。1 は最初のエレメント、2 は 2 番目のエレメントを指定します。Index パラメータが 文字列変数にないエレメントを指定する場合 (Index < 0 または Index > Length(S)) 、MecsElementToCharIndex は 0 を返します。
AnsiString 版において、マルチバイト文字セット (MBCS) を使わない環境では、MecsElementToCharIndex は単純に Index の値を返します。なぜなら、エレメントと文字に 1 対 1 の対応があるからです。それ以外の場合、MecsElementToCharIndex は文字の位置を返します。1 は最初の文字、2 は 2 番目の文字を示します。
UnicodeString / WideString 版において、サロゲートペアを使わない環境では、MecsElementToCharIndex は単純に Index の値を返します。なぜなら、エレメントと文字に 1 対 1 の対応があるからです。それ以外の場合、MecsElementToCharIndex は文字の位置を返します。1 は最初の文字、2 は 2 番目の文字を示します。
たとえば、文字列が 2 つの文字で構成され、1 エレメント文字の次に 2 エレメント文字 (マルチバイト文字 / サロゲートペア) が続いている場合、MecsElementToCharIndex は Index が 1 のときに 1 を返し、Index が 2 か 3 のときに 2 を返し、Index がそれ以外の場合に 0 を返します。
端的に言えば、MecsElementToCharIndex はエレメントインデックスから、そのエレメントを含む文字のインデックスを返す関数です。
AnsiString 版関数に CodePage を指定することで、コードページを強制する事ができます。コードページを指定しなかった場合には、Unicode 版 Delphi の場合には AnsiString のコードページ、ANSI 版 Delphi の場合には MECSUtils.DefaultAnsiCodePage 変数に設定されたコードページ (デフォルトでは規定のコードページ) が使われます。
RTL の ByteToCharIndex / ElementToCharIndex (Unicode 版 Delphi) に相当する機能です。
サンプルコード:
AnsiString(CP932)
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
A |
B |
あ |
い |
う |
C |
D |
0x41 |
0x42 |
0x82 |
0xA0 |
0x82 |
0xA2 |
0x82 |
0xA4 |
0x43 |
0x44 |
// Unicode 版 Delphi での例
type
SJISString = type AnsiString(932);
var
A: SJISString;
Idx: Integer;
begin
A := 'ABあいうCD';
Idx := ElementToCharIndex(A, 3); // 3
ShowMessage(IntToStr(Idx));
Idx := ElementToCharIndex(A, 6); // 4
ShowMessage(IntToStr(Idx));
Idx := MecsElementToCharIndex(A, 3); // 3
ShowMessage(IntToStr(Idx));
Idx := MecsElementToCharIndex(A, 6); // 4
ShowMessage(IntToStr(Idx));
end;
|
// ANSI / Unicode 版 共通の例
var
A: AnsiString;
Idx: Integer;
begin
A := 'ABあいうCD';
Idx := ByteToCharIndex(A, 3); // 3
ShowMessage(IntToStr(Idx));
Idx := ByteToCharIndex(A, 6); // 4
ShowMessage(IntToStr(Idx));
Idx := MecsElementToCharIndex(A, 3, 932); // 3
ShowMessage(IntToStr(Idx));
Idx := MecsElementToCharIndex(A, 6, 932); // 4
ShowMessage(IntToStr(Idx));
end;
|
UnicodeString / WideString
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
A |
B |
𠮷 |
野 |
屋 |
C |
D |
0x0041 |
0x0042 |
0xD842 |
0xDFB7 |
0x91CE |
0x5C4B |
0x0043 |
0x0044 |
// Unicode 版 Delphi での例
var
U: UnicodeString;
Idx: Integer;
begin
U := 'AB' + #$20BB7 + '野屋CD';
Idx := ElementToCharIndex(U, 4); // 3
ShowMessage(IntToStr(Idx));
Idx := ElementToCharIndex(U, 5); // 4
ShowMessage(IntToStr(Idx));
Idx := MecsElementToCharIndex(U, 4); // 3
ShowMessage(IntToStr(Idx));
Idx := MecsElementToCharIndex(U, 5); // 4
ShowMessage(IntToStr(Idx));
end;
|
// ANSI / Unicode 版 共通の例
var
W: WideString;
Idx: Integer;
begin
W := 'AB' + #$D842#$DFB7 + '野屋CD';
{$IFDEF UNICODE}
Idx := ElementToCharIndex(W, 4); // 3
ShowMessage(IntToStr(Idx));
Idx := ElementToCharIndex(W, 5); // 5
ShowMessage(IntToStr(Idx));
{$ELSE}
// ANSI 版 Delphi の ByteToCharIndex() に WideString 版はない
// ANSI 版 Delphi に ElementToCharIndex() はない
{$ENDIF}
Idx := MecsElementToCharIndex(W, 4); // 3
ShowMessage(IntToStr(Idx));
Idx := MecsElementToCharIndex(W, 5); // 5
ShowMessage(IntToStr(Idx));
end;
|
UTF8String(CP_UTF8/CP65001)
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
A |
B |
𠮷 |
野 |
屋 |
C |
D |
0x41 |
0x42 |
0xF0 |
0xA0 |
0xAE |
0xB7 |
0xE9 |
0x87 |
0x8E |
0xE5 |
0xB1 |
0x8B |
0x43 |
0x44 |
// Unicode 版 Delphi での例
var
U8: UTF8String;
Idx: Integer;
begin
U8 := 'AB' + #$20BB7 + '野屋CD';
Idx := ElementToCharIndex(U8, 5); // 5 (NG)
ShowMessage(IntToStr(Idx));
Idx := ElementToCharIndex(U8, 8); // 6 (NG)
ShowMessage(IntToStr(Idx));
Idx := MecsElementToCharIndex(U8, 5); // 3
ShowMessage(IntToStr(Idx));
Idx := MecsElementToCharIndex(U8, 8); // 4
ShowMessage(IntToStr(Idx));
end;
|
// ANSI 版 Delphi での例
var
U8: UTF8String;
Idx: Integer;
begin
U8 := 'AB' + #$F0#$A0#$AE#$B7 + #$E9#$87#$8E + #$E5#$B1#$8B + 'CD';
Idx := ByteToCharIndex(U8, 5); // 4 (NG)
ShowMessage(IntToStr(Idx));
Idx := ByteToCharIndex(U8, 8); // 6 (NG)
ShowMessage(IntToStr(Idx));
Idx := MecsElementToCharIndex(U8, 5, CP_UTF8); // 3
ShowMessage(IntToStr(Idx));
Idx := MecsElementToCharIndex(U8, 8, CP_UTF8); // 4
ShowMessage(IntToStr(Idx));
end;
|
MecsElementToCharLen 関数は文字列の最初の MaxLen エレメントに含まれている文字数を返します。
分野の指定
Common ルーチン
Unicode 版 Delphi の構文:
function MecsElementToCharLen(const S: RawByteString; MaxLen: Integer; CodePage: DWORD = 0): Integer;
function MecsElementToCharLen(const S: UnicodeString; MaxLen: Integer): Integer;
function MecsElementToCharLen(const S: WideString; MaxLen: Integer): Integer;
ANSI 版 Delphi の構文:
function MecsElementToCharLen(const S: AnsiString; MaxLen: Integer; CodePage: DWORD = 0): Integer;
function MecsElementToCharLen(const S: WideString; MaxLen: Integer): Integer;
説明:
MecsElementToCharLen 関数を呼び出すと、文字列の部分的な文字数がわかります。MecsElementToCharLen は MaxLen エレメントまたは文字列の最後のどちらか先に達する方までの文字数をカウントします。
AnsiString 版において、マルチバイト文字セット (MBCS) の場合、MecsElementToCharLen の戻り値が MaxLen または文字列の長さより小さくなる場合があります。
UnicodeString / WideString 版において、サロゲートペアが利用される環境の場合、MecsElementToCharLen の戻り値が MaxLen または文字列の長さより小さくなる場合があります。
端的に言えば、MecsElementToCharLen はエレメントインデックスから文字列長を返す関数です。
AnsiString 版関数に CodePage を指定することで、コードページを強制する事ができます。コードページを指定しなかった場合には、Unicode 版 Delphi の場合には AnsiString のコードページ、ANSI 版 Delphi の場合には MECSUtils.DefaultAnsiCodePage 変数に設定されたコードページ (デフォルトでは規定のコードページ) が使われます。
RTL の ByteToCharLen / ElementToCharLen (Unicode 版 Delphi) に相当する機能です。
サンプルコード:
AnsiString(CP932)
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
A |
B |
あ |
い |
う |
C |
D |
0x41 |
0x42 |
0x82 |
0xA0 |
0x82 |
0xA2 |
0x82 |
0xA4 |
0x43 |
0x44 |
// Unicode 版 Delphi での例
type
SJISString = type AnsiString(932);
var
A: SJISString;
Idx: Integer;
begin
A := 'ABあいうCD';
Idx := ElementToCharLen(A, 3); // 3
ShowMessage(IntToStr(Idx));
Idx := ElementToCharLen(A, 6); // 4
ShowMessage(IntToStr(Idx));
Idx := MecsElementToCharLen(A, 3); // 3
ShowMessage(IntToStr(Idx));
Idx := MecsElementToCharLen(A, 6); // 4
ShowMessage(IntToStr(Idx));
end;
|
// ANSI / Unicode 版 共通の例
var
A: AnsiString;
Idx: Integer;
begin
A := 'ABあいうCD';
Idx := ByteToCharLen(A, 3); // 3
ShowMessage(IntToStr(Idx));
Idx := ByteToCharLen(A, 6); // 4
ShowMessage(IntToStr(Idx));
Idx := MecsElementToCharLen(A, 3, 932); // 3
ShowMessage(IntToStr(Idx));
Idx := MecsElementToCharLen(A, 6, 932); // 4
ShowMessage(IntToStr(Idx));
end;
|
UnicodeString / WideString
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
A |
B |
𠮷 |
野 |
屋 |
C |
D |
0x0041 |
0x0042 |
0xD842 |
0xDFB7 |
0x91CE |
0x5C4B |
0x0043 |
0x0044 |
// Unicode 版 Delphi での例
var
U: UnicodeString;
Idx: Integer;
begin
U := 'AB' + #$20BB7 + '野屋CD';
Idx := ElementToCharLen(U, 4); // 3
ShowMessage(IntToStr(Idx));
Idx := ElementToCharLen(U, 5); // 4
ShowMessage(IntToStr(Idx));
Idx := MecsElementToCharLen(U, 4); // 3
ShowMessage(IntToStr(Idx));
Idx := MecsElementToCharLen(U, 5); // 4
ShowMessage(IntToStr(Idx));
end;
|
// ANSI / Unicode 版 共通の例
var
W: WideString;
Idx: Integer;
begin
W := 'AB' + #$D842#$DFB7 + '野屋CD';
{$IFDEF UNICODE}
Idx := ElementToCharLen(W, 4); // 3
ShowMessage(IntToStr(Idx));
Idx := ElementToCharLen(W, 5); // 5
ShowMessage(IntToStr(Idx));
{$ELSE}
// ANSI 版 Delphi の ByteToCharLen() に WideString版はない
// ANSI 版 Delphi に ElementToCharLen() はない
{$ENDIF}
Idx := MecsElementToCharLen(W, 4); // 3
ShowMessage(IntToStr(Idx));
Idx := MecsElementToCharLen(W, 5); // 5
ShowMessage(IntToStr(Idx));
end;
|
UTF8String(CP_UTF8/CP65001)
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
A |
B |
𠮷 |
野 |
屋 |
C |
D |
0x41 |
0x42 |
0xF0 |
0xA0 |
0xAE |
0xB7 |
0xE9 |
0x87 |
0x8E |
0xE5 |
0xB1 |
0x8B |
0x43 |
0x44 |
// Unicode 版 Delphi での例
var
U8: UTF8String;
Idx: Integer;
begin
U8 := 'AB' + #$20BB7 + '野屋CD';
Idx := ElementToCharLen(U8, 5); // 5 (NG)
ShowMessage(IntToStr(Idx));
Idx := ElementToCharLen(U8, 8); // 6 (NG)
ShowMessage(IntToStr(Idx));
Idx := MecsElementToCharLen(U8, 5); // 3
ShowMessage(IntToStr(Idx));
Idx := MecsElementToCharLen(U8, 8); // 4
ShowMessage(IntToStr(Idx));
end;
|
// ANSI 版 Delphi での例
var
U8: UTF8String;
Idx: Integer;
begin
U8 := 'AB' + #$F0#$A0#$AE#$B7 + #$E9#$87#$8E + #$E5#$B1#$8B + 'CD';
Idx := ByteToCharLen(U8, 5); // 4 (NG)
ShowMessage(IntToStr(Idx));
Idx := ByteToCharLen(U8, 8); // 6 (NG)
ShowMessage(IntToStr(Idx));
Idx := MecsElementToCharLen(U8, 5, CP_UTF8); // 3
ShowMessage(IntToStr(Idx));
Idx := MecsElementToCharLen(U8, 8, CP_UTF8); // 4
ShowMessage(IntToStr(Idx));
end;
|
MecsElementType 関数は文字列が 1 エレメントで 1 文字のエレメント, 2 エレメントで 1 文字の場合の最初のエレメント, 2 番目以降のエレメントのいずれであるかを示します。
分野の指定
Common ルーチン
Unicode 版 Delphi の構文:
function MecsElementType(const S: RawByteString; Index: Integer; CodePage: DWORD = 0): TElementType;
function MecsElementType(const S: UnicodeString; Index: Integer): TElementType;
function MecsElementType(const S: WideString; Index: Integer): TElementType;
ANSI 版 Delphi の構文:
function MecsElementType(const S: AnsiString; Index: Integer; CodePage: DWORD = 0): TElementType;
function MecsElementType(const S: WideString; Index: Integer): TElementType;
説明:
MecsElementType 関数を呼び出すと、文字列内の指定されたエレメントが、シングルエレメント文字か、マルチエレメント文字の最初のエレメントか、またはそれに続くエレメントのうちの 1 つであるのかを知ることができます。
Index は、エレメントの種類を確認するエレメントを特定します。エレメントの番号は 1 から始まります。
AnsiString 版において、マルチバイト文字セット (MBCS) を使わない環境では、ElementType は必ず etSingle を返します。それ以外の場合、ElementType は、指定されたエレメント (バイト) が完全な 1 文字を表すときに etSingle、2 バイト文字の最初のバイトを表すときに etLead、マルチバイト文字の 2 番目のバイトを表すときに etTrail を返します。
UnicodeString / WideString 版において、サロゲートペアを使わない環境では、ElementType は必ず etSingle を返します。それ以外の場合、ElementType は、指定されたエレメント (ワード) が完全な 1 文字を表すときに etSingle、サロゲートペアの最初のワードを表すときに etLead、サロゲートペアの 2 番目のワードを表すときに etTrail を返します。
etSingle |
1 つのエレメントで構成される文字。 |
etLead |
2 つ以上のエレメントで構成される文字の最初のエレメント。 |
etTrail |
2 つ以上のエレメントで構成される文字の2 つ目以降のエレメント。 |
AnsiString 版関数に CodePage を指定することで、コードページを強制する事ができます。コードページを指定しなかった場合には、Unicode 版 Delphi の場合には AnsiString のコードページ、ANSI 版 Delphi の場合には MECSUtils.DefaultAnsiCodePage 変数に設定されたコードページ (デフォルトでは規定のコードページ) が使われます。
RTL の ByteType に相当する機能です。
メモ:
Index が S の長さの範囲内にあるかどうかのチェックは一切行われません。Index が範囲外にならないようにするのは呼び出し側の責任です。
MecsInsert 手続きは部分文字列を文字列の指定された位置に挿入します。
分野の指定
Common ルーチン
Unicode 版 Delphi の構文:
procedure MecsInsert(const Source: RawByteString; var S: RawByteString; Index: Integer; CodePage: DWORD = 0);
procedure MecsInsert(const Source: UnicodeString; var S: UnicodeString; Index: Integer);
procedure MecsInsert(const Source: WideString; var S: WideString; Index: Integer);
ANSI 版 Delphi の構文:
procedure MecsInsert(const Source: AnsiString; var S: AnsiString; Index: Integer; CodePage: DWORD = 0);
procedure MecsInsert(const Source: WideString; var S: WideString; Index: Integer);
説明:
MecsInsert 手続きは Source を S に index 文字目の位置から挿入します。
Source は文字列型の式です。S は任意の長さの文字列型の変数です。Index は整数型の式です。Index は文字インデックスです。
Index が 1 未満の場合、Index は 1 にマップされます。Index が文字列の最後を過ぎている場合、Index は文字列の長さに設定され、操作が追加に変わります。
Source パラメータが空の文字列の場合、Insert は何もしません
AnsiString 版関数に CodePage を指定することで、コードページを強制する事ができます。コードページを指定しなかった場合には、Unicode 版 Delphi の場合には AnsiString のコードページ、ANSI 版 Delphi の場合には MECSUtils.DefaultAnsiCodePage 変数に設定されたコードページ (デフォルトでは規定のコードページ) が使われます。
RTL の Insert に相当する機能です。
MecsIsFullWidth 関数は文字が FULL_WIDTH であるかを判定します。
分野の指定
Common ルーチン
Unicode 版 Delphi の構文:
function MecsIsFullWidth(const S: RawByteString; CharIndex: Integer): Boolean;
function MecsIsFullWidth(const S: RawByteString; CharIndex: Integer; FarEast: Boolean; CodePage: DWORD = 0): Boolean;
function MecsIsFullWidth(const S: UnicodeString; CharIndex: Integer): Boolean;
function MecsIsFullWidth(const S: UnicodeString; CharIndex: Integer; FarEast: Boolean): Boolean;
function MecsIsFullWidth(const S: WideString; CharIndex: Integer): Boolean;
function MecsIsFullWidth(const S: WideString; CharIndex: Integer; FarEast: Boolean): Boolean;
function MecsIsFullWidth(const CodePoint: UCS4Char): Boolean;
function MecsIsFullWidth(const CodePoint: UCS4Char; FarEast: Boolean): Boolean;
ANSI 版 Delphi の構文:
function MecsIsFullWidth(const S: AnsiString; CharIndex: Integer): Boolean;
function MecsIsFullWidth(const S: AnsiString; CharIndex: Integer; FarEast: Boolean; CodePage: DWORD = 0): Boolean;
function MecsIsFullWidth(const S: WideString; CharIndex: Integer): Boolean;
function MecsIsFullWidth(const S: WideString; CharIndex: Integer; FarEast: Boolean): Boolean;
function MecsIsFullWidth(const CodePoint: UCS4Char): Boolean;
function MecsIsFullWidth(const CodePoint: UCS4Char; FarEast: Boolean): Boolean;
説明:
MecsIsFullWidth 関数は文字列 S の CharIndex 文字目が、いわゆる全角文字であるかを判定します。CodePoint を引数に持つオーバーロードされた関数は CodePoint で表されるコードポイントが、いわゆる全角文字であるかを判定します。
FarEast に True を設定すると、東アジアの文字幅が適用されます。
FarEast を指定しなかった場合には、FarEast の条件として SysLocale.FarEast が使われます。
AnsiString 版関数に CodePage を指定することで、コードページを強制する事ができます。コードページを指定しなかった場合には、Unicode 版 Delphi の場合には AnsiString のコードページ、ANSI 版 Delphi の場合には MECSUtils.DefaultAnsiCodePage 変数に設定されたコードページ (デフォルトでは規定のコードページ) が使われます。
サンプルコード:
以下はよくある"文字列を右詰めする"サンプルコードです。フォームに Memo1、Memo2 と Button1 を貼り付けて実行してみましょう。
// Unicode 版 Delphi での例
procedure TForm1.Button1Click(Sender: TObject);
var
U: UnicodeString;
begin
U := 'Aαあ' + #$20BB7;
Memo1.Lines.Clear;
Memo1.Font.Name := 'MS ゴシック';
Memo1.Font.Size := 10;
Memo1.Font.CharSet := SHIFTJIS_CHARSET;
Memo2.Lines.Clear;
Memo2.Font.Name := 'Courier New';
Memo2.Font.Size := 10;
Memo2.Font.CharSet := ANSI_CHARSET;
Memo1.Lines.Add(StringOfChar('*', 10));
Memo1.Lines.Add(StringOfChar(' ', 10 - Length(U)) + U);
Memo2.Lines.Add(StringOfChar('*', 10));
Memo2.Lines.Add(StringOfChar(' ', 10 - Length(U)) + U);
end;
|
さて、結果はいかがでしたか?プロポーショナルフォントでもないのに揃いませんね。実はこのコードには 3 つの問題点があります。
- 'A' も 'あ' も Length() ではサイズが 1 になる
Unicode (UTF-16) では 'A' も 'あ' もエレメントサイズは 1 です。
- 'α' は東アジアでは全角サイズ、それ以外の地域では半角サイズで描画される。
Unicode (UTF-16) に於いて 'α' のエレメントサイズは 1 ですが、国や地域、フォントによって描画されるサイズが異なる文字があります。ギリシャ文字はその一部です。
- #$20BB7 はサロゲートペア。
U+20BB7 のエレメントサイズは 2 (#$D842 #$DFB7) で、全角サイズで描画されています。
Unicode で正しく右詰めするには以下のようなコードを記述する必要があります。
// Unicode 版 Delphi での例
procedure TForm1.Button1Click(Sender: TObject);
var
U: UnicodeString;
i: Integer;
Cnt: Integer;
begin
U := 'Aαあ' + #$20BB7;
Memo1.Lines.Clear;
Memo1.Font.Name := 'MS ゴシック';
Memo1.Font.Size := 10;
Memo1.Font.CharSet := SHIFTJIS_CHARSET;
Memo2.Lines.Clear;
Memo2.Font.Name := 'Courier New';
Memo2.Font.Size := 10;
Memo2.Font.CharSet := ANSI_CHARSET;
Memo1.Lines.Add(StringOfChar('*', 10));
Cnt := 0;
for i:=1 to MecsLength(U) do
if MecsIsFullWidth(U, i, IsFarEastCharSet(Memo1.Font.CharSet)) then
Inc(Cnt, 2)
else
Inc(Cnt, 1);
Memo1.Lines.Add(StringOfChar(' ', 10 - Cnt) + U);
Memo2.Lines.Add(StringOfChar('*', 10));
Cnt := 0;
for i:=1 to MecsLength(U) do
if MecsIsFullWidth(U, i, IsFarEastCharSet(Memo2.Font.CharSet)) then
Inc(Cnt, 2)
else
Inc(Cnt, 1);
Memo2.Lines.Add(StringOfChar(' ', 10 - Cnt) + U);
end;
|
サンプルでは東アジアの判定に IsFarEastCharSet を使いましたが、 IsFarEastLCID を使う事もできます。状況に応じてフォントやLCID等、東アジアを判定する方法を変更する必要があります。
関連情報:
MecsIsLeadElement 関数は文字列のエレメントが文字を構成する最初のエレメントであるかを示します。
分野の指定
Common ルーチン
Unicode 版 Delphi の構文:
function MecsIsLeadElement(TestChar: AnsiChar; CodePage: DWORD = 0): Boolean;
function MecsIsLeadElement(TestChar: UnicodeChar): Boolean;
ANSI 版 Delphi の構文:
function MecsIsLeadElement(TestChar: AnsiChar; CodePage: DWORD = 0): Boolean;
function MecsIsLeadElement(TestChar: WideChar): Boolean;
説明:
MecsIsLeadElement 関数は文字列のエレメントが文字を構成する最初のエレメントであるかを示します。
AnsiString 版においては、マルチバイト文字セット (MBCS) の最初のバイト (Lead Byte) であるかを判定します。
UnicodeString / WideString 版においては、サロゲートペアの最初のワード (High Surrogate) であるかを判定します。
AnsiChar 版を使う際には CodePage を設定し、コードページを強制すべきです。何故なら、Unicode 版 Delphi であっても AnsiChar のコードページを自動的に知る事はできないからです。
MecsIsMECElement 関数は文字列のエレメントが複数のエレメントで文字を構成するエレメントであるかを示します。
分野の指定
Common ルーチン
Unicode 版 Delphi の構文:
function MecsIsMECElement(TestChar: AnsiChar; CodePage: DWORD = 0): Boolean;
function MecsIsMECElement(TestChar: UnicodeChar): Boolean;
ANSI 版 Delphi の構文:
function MecsIsMECElement(TestChar: AnsiChar; CodePage: DWORD = 0): Boolean;
function MecsIsMECElement(TestChar: WideChar): Boolean;
説明:
MecsIsMECElement 関数は文字列のエレメントが複数のエレメントで文字を構成するエレメントであるかを示します。
AnsiString 版においては、マルチバイト文字セット (MBCS) を構成するエレメントであるかを判定します。
UnicodeString / WideString 版においては、サロゲートペアを構成するエレメントであるかを判定します。
AnsiChar 版を使う際には CodePage を設定し、コードページを強制すべきです。何故なら、Unicode 版 Delphi であっても AnsiChar のコードページを自動的に知る事はできないからです。
MecsIsTrailElement 関数は文字列のエレメントが文字を構成する 2 番目以降のエレメントであるかを示します。
分野の指定
Common ルーチン
Unicode 版 Delphi の構文:
function MecsIsTrailElement(TestChar: AnsiChar): Boolean;
function MecsIsTrailElement(TestChar: AnsiChar; CodePage: DWORD = 0): Boolean;
function MecsIsTrailElement(TestChar: UnicodeChar): Boolean;
ANSI 版 Delphi の構文:
function MecsIsTrailElement(TestChar: AnsiChar): Boolean;
function MecsIsTrailElement(TestChar: AnsiChar; CodePage: DWORD = 0): Boolean;
function MecsIsTrailElement(TestChar: WideChar): Boolean;
説明:
MecsIsTrailElement 関数は文字列のエレメントが文字を構成する 2 番目以降のエレメントであるかを示します。
AnsiString 版においては、マルチバイト文字セット (MBCS) の2 番目以降のバイト (Trail Byte) であるかを判定します。
UnicodeString / WideString 版においては、サロゲートペアの2 番目のワード (Low Surrogate) であるかを判定します。
AnsiChar 版を使う際には CodePage を設定し、コードページを強制すべきです。何故なら、Unicode 版 Delphi であっても AnsiChar のコードページを自動的に知る事はできないからです。
また、マルチバイト Ansi においては Lead-Byte と Trail-Byte の範囲が重複している事が多いので、MecsIsTrailElement 単体での使用は避けるべきです。
MecsLeftStr 関数は文字列の最初に表示される指定された長さの部分文字列を返します。
分野の指定
Common ルーチン
Unicode 版 Delphi の構文:
function MecsLeftStr(const AText: RawByteString; const ACount: Integer; CodePage: DWORD = 0): RawByteString;
function MecsLeftStr(const AText: UnicodeString; const ACount: Integer): UnicodeString;
function MecsLeftStr(const AText: WideString; const ACount: Integer): WideString;
ANSI 版 Delphi の構文:
function MecsLeftStr(const AText: AnsiString; const ACount: Integer; CodePage: DWORD = 0): AnsiString;
function MecsLeftStr(const AText: WideString; const ACount: Integer): WideString;
説明:
MecsLeftStr 関数は、AText の先頭から ACount で指定された文字数以内の文字数を返します。
AnsiString 版関数に CodePage を指定することで、コードページを強制する事ができます。コードページを指定しなかった場合には、Unicode 版 Delphi の場合には AnsiString のコードページ、ANSI 版 Delphi の場合には MECSUtils.DefaultAnsiCodePage 変数に設定されたコードページ (デフォルトでは規定のコードページ) が使われます。
RTL の LeftStr/AnsiLeftStr に相当する機能です。AnsiString 版 は AnsiLeftStr と違い、ラウンドトリップの問題を引き起こしません (※Delphi 2009 Update 3 以降ではラウンドトリップしません)。UnicodeString / WideString 版はサロゲートペアを考慮します。
サンプルコード:
AnsiString(CP932)
1 |
2 |
3 |
4 |
5 |
6 |
7 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
A |
B |
あ |
い |
う |
C |
D |
0x41 |
0x42 |
0x82 |
0xA0 |
0x82 |
0xA2 |
0x82 |
0xA4 |
0x43 |
0x44 |
// Unicode 版 Delphi での例
type
SJISString = type AnsiString(932);
var
A: SJISString;
begin
// LeftStr
A := 'ABあいうCD';
A := StrUtils.LeftStr(A, 3);
ShowMessage(A); // AB?
// LeftBStr
A := 'ABあいうCD';
A := StrUtils.LeftBStr(A, 3);
ShowMessage(A); // AB?
// AnsiLeftStr
A := 'ABあいうCD';
A := AnsiStrings.AnsiLeftStr(A, 3);
ShowMessage(A); // ABあ
// MecsLeftStr
A := 'ABあいうCD';
A := MecsLeftStr(A, 3);
ShowMessage(A); // ABあ
end;
|
// ANSI 版 Delphi での例
var
A: AnsiString;
begin
// LeftStr
A := 'ABあいうCD';
A := LeftStr(A, 3);
ShowMessage(A); // AB?
// LeftBStr
A := 'ABあいうCD';
A := LeftBStr(A, 3);
ShowMessage(A); // AB?
// AnsiLeftStr
A := 'ABあいうCD';
A := AnsiLeftStr(A, 3);
ShowMessage(A); // ABあ
// MecsLeftStr
A := 'ABあいうCD';
A := MecsLeftStr(A, 3, 932);
ShowMessage(A); // ABあ
end;
|
ヘルプを読む限りでは AnsiLeftStr と LeftStr には差異がないはずなのですが、結果からすると LeftStr と LeftBStr が同等のようです。AnsiLeftStr は正常に動作しているように見えます。しかし、次のコードではどうでしょうか?
AnsiString(CP932)
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
A |
B |
∵ |
∵ |
∵ |
C |
D |
0x41 |
0x42 |
0x81 |
0xE6 |
0x87 |
0xFA |
0x5B |
0xA4 |
0x43 |
0x44 |
// Unicode 版 Delphi での例
type
SJISString = type AnsiString(932);
var
A: SJISString;
procedure ShowBinary(S: RawByteString);
var
i: Integer;
Dmy: RawByteString;
begin
Dmy := #$0D#$0A;
for i:=1 to Length(S) do
begin
Dmy := Dmy + AnsiStrings.Format('%.2x', [Ord(S[i])]);
if i < Length(S) then
Dmy := Dmy + ',';
end;
ShowMessage(S + Dmy);
end;
begin
// AnsiLeftStr
A := 'A';
A := A + 'B';
A := A + #$81#$E6;
A := A + #$87#$9A;
A := A + #$FA#$5B;
A := A + 'C';
A := A + 'D';
A := StrUtils.AnsiLeftStr(A, 5);
ShowBinary(A); // #$41 #$42 #$81#$E6 #$81#$E6 #$81#$E6 (NG)
// MecsLeftStr
A := 'A';
A := A + 'B';
A := A + #$81#$E6;
A := A + #$87#$9A;
A := A + #$FA#$5B;
A := A + 'C';
A := A + 'D';
A := MecsLeftStr(A, 5);
ShowBinary(A); // #$41 #$42 #$81#$E6 #$87#$9A #$FA#$5B
end;
|
// ANSI 版 Delphi での例
var
A: AnsiString;
procedure ShowBinary(S: AnsiString);
var
i: Integer;
Dmy: AnsiString;
begin
Dmy := #$0D#$0A;
for i:=1 to Length(S) do
begin
Dmy := Dmy + Format('%.2x', [Ord(S[i])]);
if i < Length(S) then
Dmy := Dmy + ',';
end;
ShowMessage(S + Dmy);
end;
begin
// AnsiLeftStr
A := 'AB' + #$81#$E6 + #$87#$9A + #$FA#$5B + 'CD';
A := AnsiLeftStr(A, 5);
ShowBinary(A); // #$41 #$42 #$81#$E6 #$81#$E6 #$81#$E6 (NG)
// MecsLeftStr
A := 'AB' + #$81#$E6 + #$87#$9A + #$FA#$5B + 'CD';
A := MecsLeftStr(A, 5, 932);
ShowBinary(A); // #$41 #$42 #$81#$E6 #$87#$9A #$FA#$5B #$43 #$44
end;
|
AnsiLeftStr の AnsiString 版は内部で WideString/UnicodeString へ変換してから文字列操作を行い、結果を AnsiString で返します。そのため、ラウンドトリップ変換を行う事になり、CP932 の"字形が同じで別のコードポイントの文字"は Unicode の一つのコードポイントにまとめられてしまいます。
UnicodeString / WideString
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
A |
B |
𠮷 |
野 |
屋 |
C |
D |
0x0041 |
0x0042 |
0xD842 |
0xDFB7 |
0x91CE |
0x5C4B |
0x0043 |
0x0044 |
// Unicode 版 Delphi での例
var
U: UnicodeString;
Idx: Integer;
begin
// LeftStr
U := 'AB' + #$20BB7 + '野屋CD';
U := LeftStr(U, 5); // AB𠮷野 (サロゲートペアが考慮されない)
ShowMessage(U);
// AnsiLeftStr
U := 'AB' + #$20BB7 + '野屋CD';
U := AnsiLeftStr(U, 5); // AB𠮷野 (サロゲートペアが考慮されない)
ShowMessage(U);
// MecsLeftStr
U := 'AB' + #$20BB7 + '野屋CD';
U := MecsLeftStr(U, 5); // AB𠮷野屋
ShowMessage(U);
end;
|
// ANSI 版 Delphi での例
// (通常、ShowMessage ではサロゲートペアを表示できない)
var
W: WideString;
Idx: Integer;
begin
// LeftStr
W := 'AB' + #$D842#$DFB7 + '野屋CD';
W := LeftStr(W, 5); // AB𠮷野 (サロゲートペアが考慮されない)
ShowMessage(W);
// AnsiLeftStr
W := 'AB' + #$D842#$DFB7 + '野屋CD';
W := AnsiLeftStr(W, 5); // AB𠮷野 (サロゲートペアが考慮されない)
ShowMessage(W);
// MecsLeftStr
W := 'AB' + #$D842#$DFB7 + '野屋CD';
W := MecsLeftStr(W, 5); // AB𠮷野屋
ShowMessage(W);
end;
|
UTF8String(CP_UTF8/CP65001)
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
A |
B |
𠮷 |
野 |
屋 |
C |
D |
0x41 |
0x42 |
0xF0 |
0xA0 |
0xAE |
0xB7 |
0xE9 |
0x87 |
0x8E |
0xE5 |
0xB1 |
0x8B |
0x43 |
0x44 |
// Unicode 版 Delphi での例
var
U8: UTF8String;
Idx: Integer;
procedure ShowBinary(S: RawByteString);
var
i: Integer;
Dmy: RawByteString;
begin
Dmy := #$0D#$0A;
for i:=1 to Length(S) do
begin
Dmy := Dmy + AnsiStrings.Format('%.2x', [Ord(S[i])]);
if i < Length(S) then
Dmy := Dmy + ',';
end;
ShowMessage(S + Dmy);
end;
begin
// LeftStr
U8 := 'AB' + #$20BB7 + '野屋CD';
U8 := StrUtils.LeftStr(U8, 5); // #$41#$42#$3F#$3F#$E3#$83#$BB (NG)
ShowBinary(U8);
// AnsiLeftStr
U8 := 'AB' + #$20BB7 + '野屋CD';
U8 := AnsiStrings.AnsiLeftStr(U8, 5); // #$41#$42#$3F#$3F#$E9#$87#$8E (NG)
ShowBinary(U8);
// MecsLeftStr
U8 := 'AB' + #$20BB7 + '野屋CD';
U8 := MecsLeftStr(U8, 5); // #$41 #$42 #$F0#$A0#$AE#$B7 #$E9#$87#$8E #$E5#$B1#$8B
ShowBinary(U8);
end;
|
// ANSI 版 Delphi での例
// (通常、ShowMessage ではサロゲートペアを表示できない)
var
U8: UTF8String;
Idx: Integer;
procedure ShowBinary(S: AnsiString);
var
i: Integer;
Dmy: AnsiString;
begin
Dmy := #$0D#$0A;
for i:=1 to Length(S) do
begin
Dmy := Dmy + Format('%.2x', [Ord(S[i])]);
if i < Length(S) then
Dmy := Dmy + ',';
end;
ShowMessage(S + Dmy);
end;
begin
// LeftStr
U8 := 'AB' + #$F0#$A0#$AE#$B7 + #$E9#$87#$8E + #$E5#$B1#$8B + 'CD';
U8 := LeftStr(U8, 5); // #$41#$42#$F0#$A0#$AE (NG)
ShowBinary(U8);
// AnsiLeftStr
U8 := 'AB' + #$F0#$A0#$AE#$B7 + #$E9#$87#$8E + #$E5#$B1#$8B + 'CD';
U8 := AnsiLeftStr(U8, 5); // #$41#$42#$F0#$A0#$AE#$B7 (NG)
ShowBinary(U8);
// MecsLeftStr
U8 := 'AB' + #$F0#$A0#$AE#$B7 + #$E9#$87#$8E + #$E5#$B1#$8B + 'CD';
U8 := MecsLeftStr(U8, 5, CP_UTF8); // #$41 #$42 #$F0#$A0#$AE#$B7 #$E9#$87#$8E #$E5#$B1#$8B
ShowBinary(U8);
end;
|
関連情報:
MecsLength 関数は文字列内の文字数を返します
分野の指定
Common ルーチン
Unicode 版 Delphi の構文:
function MecsLength(const S: RawByteString): Integer;
function MecsLength(const S: RawByteString; CodePage: DWORD = 0): Integer;
function MecsLength(const S: UnicodeString): Integer;
function MecsLength(const S: WideString): Integer;
ANSI 版 Delphi の構文:
function MecsLength(const S: AnsiString): Integer;
function MecsLength(const S: AnsiString; CodePage: DWORD = 0): Integer;
function MecsLength(const S: WideString): Integer;
説明:
MecsLength 関数は文字列内の文字数を返します。マルチバイト文字 / サロゲートペア が考慮されます。
AnsiString 版関数に CodePage を指定することで、コードページを強制する事ができます。コードページを指定しなかった場合には、Unicode 版 Delphi の場合には AnsiString のコードページ、ANSI 版 Delphi の場合には MECSUtils.DefaultAnsiCodePage 変数に設定されたコードページ (デフォルトでは規定のコードページ) が使われます。
RTL の Length の文字数版ですが、動的配列はサポートされません。
MecsMidStr 関数は文字列内の指定された部分に表示される、指定された長さの部分文字列を返します。
分野の指定
Common ルーチン
Unicode 版 Delphi の構文:
function MecsMidStr(const AText: RawByteString; const AStart, ACount: Integer): RawByteString;
function MecsMidStr(const AText: RawByteString; const AStart, ACount: Integer; CodePage: DWORD = 0): RawByteString;
function MecsMidStr(const AText: UnicodeString; const AStart, ACount: Integer): UnicodeString;
function MecsMidStr(const AText: WideString; const AStart, ACount: Integer): WideString;
ANSI 版 Delphi の構文:
function MecsMidStr(const AText: AnsiString; const AStart, ACount: Integer): AnsiString;
function MecsMidStr(const AText: AnsiString; const AStart, ACount: Integer; CodePage: DWORD = 0): AnsiString;
function MecsMidStr(const AText: WideString; const AStart, ACount: Integer): WideString;
説明:
MecsMidStr は、AText の AStart 文字目から Count プロパティで指定した文字数の部分文字列を返します。
もし AStart が AText 文字列の長さよりも大きい場合、MidStr 関数は空文字列を返します。
Count が有効な文字数以上の値を指定している場合は、AText の AStart 文字目から AText の最後までの文字のみが返されます。
AnsiString 版関数に CodePage を指定することで、コードページを強制する事ができます。コードページを指定しなかった場合には、Unicode 版 Delphi の場合には AnsiString のコードページ、ANSI 版 Delphi の場合には MECSUtils.DefaultAnsiCodePage 変数に設定されたコードページ (デフォルトでは規定のコードページ) が使われます。
RTL の MidStr/AnsiMidStr に相当する機能です。AnsiString 版 は AnsiMidStr と違い、ラウンドトリップの問題を引き起こしません (※Delphi 2009 Update 3 以降ではラウンドトリップしません)。UnicodeString / WideString 版はサロゲートペアを考慮します。
サンプルコード:
AnsiString(CP932)
1 |
2 |
3 |
4 |
5 |
6 |
7 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
A |
B |
あ |
い |
う |
C |
D |
0x41 |
0x42 |
0x82 |
0xA0 |
0x82 |
0xA2 |
0x82 |
0xA4 |
0x43 |
0x44 |
// Unicode 版 Delphi での例
type
SJISString = type AnsiString(932);
var
A: SJISString;
begin
// MidStr
A := 'ABあいうCD';
A := StrUtils.MidStr(A, 2, 3);
ShowMessage(A); // Bあ
// MidBStr
A := 'ABあいうCD';
A := StrUtils.MidBStr(A, 2, 3);
ShowMessage(A); // Bあ
// AnsiMidStr
A := 'ABあいうCD';
A := AnsiStrings.AnsiMidStr(A, 2, 3);
ShowMessage(A); // Bあい
// MecsMidStr
A := 'ABあいうCD';
A := MecsMidStr(A, 2, 3);
ShowMessage(A); // Bあい
end;
|
// ANSI 版 Delphi での例
var
A: AnsiString;
begin
// MidStr
A := 'ABあいうCD';
A := MidStr(A, 2, 3);
ShowMessage(A); // Bあ
// MidBStr
A := 'ABあいうCD';
A := MidBStr(A, 2, 3);
ShowMessage(A); // Bあ
// AnsiMidStr
A := 'ABあいうCD';
A := AnsiMidStr(A, 2, 3);
ShowMessage(A); // Bあい
// MecsMidStr
A := 'ABあいうCD';
A := MecsMidStr(A, 2, 3, 932);
ShowMessage(A); // Bあい
end;
|
ヘルプを読む限りでは AnsiMidStr と MidStr には差異がないはずなのですが、結果からすると MidStr と MidBStr が同等のようです。AnsiMidStr は正常に動作しているように見えます。しかし、次のコードではどうでしょうか?
AnsiString(CP932)
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
A |
B |
∵ |
∵ |
∵ |
C |
D |
0x41 |
0x42 |
0x81 |
0xE6 |
0x87 |
0xFA |
0x5B |
0xA4 |
0x43 |
0x44 |
// Unicode 版 Delphi での例
type
SJISString = type AnsiString(932);
var
A: SJISString;
procedure ShowBinary(S: RawByteString);
var
i: Integer;
Dmy: RawByteString;
begin
Dmy := #$0D#$0A;
for i:=1 to Length(S) do
begin
Dmy := Dmy + AnsiStrings.Format('%.2x', [Ord(S[i])]);
if i < Length(S) then
Dmy := Dmy + ',';
end;
ShowMessage(S + Dmy);
end;
begin
// AnsiMidStr
A := 'A';
A := A + 'B';
A := A + #$81#$E6;
A := A + #$87#$9A;
A := A + #$FA#$5B;
A := A + 'C';
A := A + 'D';
A := StrUtils.AnsiMidStr(A, 3, 3);
ShowBinary(A); // #$81#$E6 #$81#$E6 #$81#$E6 (NG)
// MecsMidStr
A := 'A';
A := A + 'B';
A := A + #$81#$E6;
A := A + #$87#$9A;
A := A + #$FA#$5B;
A := A + 'C';
A := A + 'D';
A := MecsMidStr(A, 3, 3);
ShowBinary(A); // #$81#$E6 #$87#$9A #$FA#$5B
end;
|
// ANSI 版 Delphi での例
var
A: AnsiString;
procedure ShowBinary(S: AnsiString);
var
i: Integer;
Dmy: AnsiString;
begin
Dmy := #$0D#$0A;
for i:=1 to Length(S) do
begin
Dmy := Dmy + Format('%.2x', [Ord(S[i])]);
if i < Length(S) then
Dmy := Dmy + ',';
end;
ShowMessage(S + Dmy);
end;
begin
// AnsiMidStr
A := 'AB' + #$81#$E6 + #$87#$9A + #$FA#$5B + 'CD';
A := AnsiMidStr(A, 3, 3);
ShowBinary(A); // #$81#$E6 #$81#$E6 #$81#$E6 (NG)
// MecsMidStr
A := 'AB' + #$81#$E6 + #$87#$9A + #$FA#$5B + 'CD';
A := MecsMidStr(A, 3, 3);
ShowBinary(A); // #$81#$E6 #$87#$9A #$FA#$5B
end;
|
AnsiMidStr の AnsiString 版は内部で WideString/UnicodeString へ変換してから文字列操作を行い、結果を AnsiString で返します。そのため、ラウンドトリップ変換を行う事になり、CP932 の"字形が同じで別のコードポイントの文字"は Unicode の一つのコードポイントにまとめられてしまいます。
UnicodeString / WideString
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
A |
B |
𠮷 |
野 |
屋 |
C |
D |
0x0041 |
0x0042 |
0xD842 |
0xDFB7 |
0x91CE |
0x5C4B |
0x0043 |
0x0044 |
// Unicode 版 Delphi での例
var
U: UnicodeString;
Idx: Integer;
begin
// MidStr
U := 'AB' + #$20BB7 + '野屋CD';
U := MidStr(U, 3, 3);
ShowMessage(U); // 𠮷野 (サロゲートペアが考慮されない)
// AnsiMidStr
U := 'AB' + #$20BB7 + '野屋CD';
U := AnsiMidStr(U, 3, 3); // 𠮷野 (サロゲートペアが考慮されない)
ShowMessage(U);
// MecsMidStr
U := 'AB' + #$20BB7 + '野屋CD';
U := MecsMidStr(U, 3, 3);
ShowMessage(U); // 𠮷野屋
end;
|
// ANSI 版 Delphi での例
// (通常、ShowMessage ではサロゲートペアを表示できない)
var
W: WideString;
Idx: Integer;
begin
// MidStr
W := 'AB' + #$D842#$DFB7 + '野屋CD';
W := MidStr(W, 3, 3);
ShowMessage(W); // 𠮷野 (サロゲートペアが考慮されない)
// AnsiMidStr
W := 'AB' + #$D842#$DFB7 + '野屋CD';
W := AnsiMidStr(W, 3, 3); // 𠮷野 (サロゲートペアが考慮されない)
ShowMessage(W);
// MecsMidStr
W := 'AB' + #$D842#$DFB7 + '野屋CD';
W := MecsMidStr(W, 3, 3);
ShowMessage(W); // 𠮷野屋
end;
|
UTF8String(CP_UTF8/CP65001)
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
A |
B |
𠮷 |
野 |
屋 |
C |
D |
0x41 |
0x42 |
0xF0 |
0xA0 |
0xAE |
0xB7 |
0xE9 |
0x87 |
0x8E |
0xE5 |
0xB1 |
0x8B |
0x43 |
0x44 |
// Unicode 版 Delphi での例
var
U8: UTF8String;
Idx: Integer;
procedure ShowBinary(S: RawByteString);
var
i: Integer;
Dmy: RawByteString;
begin
Dmy := #$0D#$0A;
for i:=1 to Length(S) do
begin
Dmy := Dmy + AnsiStrings.Format('%.2x', [Ord(S[i])]);
if i < Length(S) then
Dmy := Dmy + ',';
end;
ShowMessage(S + Dmy);
end;
begin
// MidStr
U8 := 'AB' + #$20BB7 + '野屋CD';
U8 := StrUtils.MidStr(U8, 3, 3); // #$3F#$3F#$E3#$83#$BB (NG)
ShowBinary(U8);
// AnsiMidStr
U8 := 'AB' + #$20BB7 + '野屋CD';
U8 := AnsiStrings.AnsiMidStr(U8, 3, 3); // #$3F#$3F#$E9#$87#$8E (NG)
ShowBinary(U8);
// MecsMidStr
U8 := 'AB' + #$20BB7 + '野屋CD';
U8 := MecsMidStr(U8, 3, 3); // #$F0#$A0#$AE#$B7 #$E9#$87#$8E #$E5#$B1#$8B
ShowBinary(U8);
end;
|
// ANSI 版 Delphi での例
// (通常、ShowMessage ではサロゲートペアを表示できない)
var
U8: UTF8String;
Idx: Integer;
procedure ShowBinary(S: AnsiString);
var
i: Integer;
Dmy: AnsiString;
begin
Dmy := #$0D#$0A;
for i:=1 to Length(S) do
begin
Dmy := Dmy + Format('%.2x', [Ord(S[i])]);
if i < Length(S) then
Dmy := Dmy + ',';
end;
ShowMessage(S + Dmy);
end;
begin
// MidStr
U8 := 'AB' + #$F0#$A0#$AE#$B7 + #$E9#$87#$8E + #$E5#$B1#$8B + 'CD';
U8 := MidStr(U8, 3, 3); // #$F0#$A0#$AE (NG)
ShowBinary(U8);
// AnsiMidStr
U8 := 'AB' + #$F0#$A0#$AE#$B7 + #$E9#$87#$8E + #$E5#$B1#$8B + 'CD';
U8 := AnsiMidStr(U8, 3, 3); // #$F0#$A0#$AE#$B7 (NG)
ShowBinary(U8);
// MecsMidStr
U8 := 'AB' + #$F0#$A0#$AE#$B7 + #$E9#$87#$8E + #$E5#$B1#$8B + 'CD';
U8 := MecsMidStr(U8, 3, 3, CP_UTF8); // #$F0#$A0#$AE#$B7 #$E9#$87#$8E #$E5#$B1#$8B
ShowBinary(U8);
end;
|
関連情報:
MecsNextCharIndex 関数は次の文字のエレメントインデックスを返します。
分野の指定
Common ルーチン
Unicode 版 Delphi の構文:
function MecsNextCharIndex(const S: RawByteString; Index: Integer): Integer;
function MecsNextCharIndex(const S: RawByteString; Index: Integer; CodePage: DWORD = 0): Integer;
function MecsNextCharIndex(const S: UnicodeString; Index: Integer): Integer;
function MecsNextCharIndex(const S: WideString; Index: Integer): Integer;
ANSI 版 Delphi の構文:
function MecsNextCharIndex(const S: AnsiString; Index: Integer): Integer;
function MecsNextCharIndex(const S: AnsiString; Index: Integer; CodePage: DWORD = 0): Integer;
function MecsNextCharIndex(const S: WideString; Index: Integer): Integer;
説明:
MecsNextCharIndex は、Index 文字目から始まる文字に続く文字の最初のエレメントのエレメントインデックスを返します。
AnsiString 版関数に CodePage を指定することで、コードページを強制する事ができます。コードページを指定しなかった場合には、Unicode 版 Delphi の場合には AnsiString のコードページ、ANSI 版 Delphi の場合には MECSUtils.DefaultAnsiCodePage 変数に設定されたコードページ (デフォルトでは規定のコードページ) が使われます。
RTL の NextCharIndex に相当する機能です。
Unicode 版 Delphi では NextCharIndex (AnsiString 版) が AnsiStrings 名前空間と SysUtils 名前空間に重複して存在します (オーバーロードされたものではありません)。
そのため、AnsiStrings を uses していると"E2251 'CharLength' へのオーバーロード呼び出しはあいまいです"が発生してしまいます。このような場合には、"AnsiStrings.NextCharIndex"のように名前空間を明示する必要があります。
MecsReverseString 関数は指定した文字列の向きを逆にしたものを返します。
分野の指定
Common ルーチン
Unicode 版 Delphi の構文:
function MecsReverseString(const AText: RawByteString): RawByteString;
function MecsReverseString(const AText: RawByteString; CodePage: DWORD = 0): RawByteString;
function MecsReverseString(const AText: UnicodeString): UnicodeString;
function MecsReverseString(const AText: WideString): WideString;
ANSI 版 Delphi の構文:
function MecsReverseString(const AText: AnsiString): AnsiString;
function MecsReverseString(const AText: AnsiString; CodePage: DWORD = 0): AnsiString;
function MecsReverseString(const AText: WideString): WideString;
説明:
MecsReverseString 関数は、AText で指定した値の文字を逆向きに配置したものを返します。
AnsiString 版関数に CodePage を指定することで、コードページを強制する事ができます。コードページを指定しなかった場合には、Unicode 版 Delphi の場合には AnsiString のコードページ、ANSI 版 Delphi の場合には MECSUtils.DefaultAnsiCodePage 変数に設定されたコードページ (デフォルトでは規定のコードページ) が使われます。
RTL の ReverseString/AnsiReverseString に相当する機能です。AnsiString 版は AnsiReverseString と違い、ラウンドトリップの問題を引き起こしません (※Delphi 2009 Update 3 以降ではラウンドトリップしません)。UnicodeString / WideString 版はサロゲートペアを考慮します。
関連情報:
MecsRightStr 関数は文字列の最後に表示される指定された長さの部分文字列を返します。
分野の指定
Common ルーチン
Unicode 版 Delphi の構文:
function MecsRightStr(const AText: RawByteString; const ACount: Integer): RawByteString;
function MecsRightStr(const AText: RawByteString; const ACount: Integer; CodePage: DWORD = 0): RawByteString;
function MecsRightStr(const AText: UnicodeString; const ACount: Integer): UnicodeString;
function MecsRightStr(const AText: WideString; const ACount: Integer): WideString;
ANSI 版 Delphi の構文:
function MecsRightStr(const AText: AnsiString; const ACount: Integer): AnsiString;
function MecsRightStr(const AText: AnsiString; const ACount: Integer; CodePage: DWORD = 0): AnsiString;
function MecsRightStr(const AText: WideString; const ACount: Integer): WideString;
説明:
MecsRightStr 関数は、AText の末尾から ACount 以内の文字数を返します。したがって、たとえば、AText が 'Programmer' という文字列で、ACount が 7 であるとすると、MecsRightStr は 'grammer' という文字列を返します。
AnsiString 版関数に CodePage を指定することで、コードページを強制する事ができます。コードページを指定しなかった場合には、Unicode 版 Delphi の場合には AnsiString のコードページ、ANSI 版 Delphi の場合には MECSUtils.DefaultAnsiCodePage 変数に設定されたコードページ (デフォルトでは規定のコードページ) が使われます。
RTL の RightStr/AnsiRightStr に相当する機能です。AnsiString 版は AnsiRightStr と違い、ラウンドトリップの問題を引き起こしません (※Delphi 2009 Update 3 以降ではラウンドトリップしません)。UnicodeString / WideString 版はサロゲートペアを考慮します。
サンプルコード:
AnsiString(CP932)
1 |
2 |
3 |
4 |
5 |
6 |
7 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
A |
B |
あ |
い |
う |
C |
D |
0x41 |
0x42 |
0x82 |
0xA0 |
0x82 |
0xA2 |
0x82 |
0xA4 |
0x43 |
0x44 |
// Unicode 版 Delphi での例
type
SJISString = type AnsiString(932);
var
A: SJISString;
begin
// RightStr
A := 'ABあいうCD';
A := StrUtils.RightStr(A, 3);
ShowMessage(A); // ?CD
// RightBStr
A := 'ABあいうCD';
A := StrUtils.RightBStr(A, 3);
ShowMessage(A); // ?CD
// AnsiRightStr
A := 'ABあいうCD';
A := AnsiStrings.AnsiRightStr(A, 3);
ShowMessage(A); // うCD
// MecsRightStr
A := 'ABあいうCD';
A := MecsRightStr(A, 3);
ShowMessage(A); // うCD
end;
|
// ANSI 版 Delphi での例
var
A: AnsiString;
begin
// RightStr
A := 'ABあいうCD';
A := RightStr(A, 3);
ShowMessage(A); // ?CD
// RightBStr
A := 'ABあいうCD';
A := RightBStr(A, 3);
ShowMessage(A); // ?CD
// AnsiRightStr
A := 'ABあいうCD';
A := AnsiRightStr(A, 3);
ShowMessage(A); // うCD
// MecsRightStr
A := 'ABあいうCD';
A := MecsRightStr(A, 3, 932);
ShowMessage(A); // うCD
end;
|
ヘルプを読む限りでは AnsiRightStr と RightStr には差異がないはずなのですが、結果からすると RightStr と RightBStr が同等のようです。AnsiRightStr は正常に動作しているように見えます。しかし、次のコードではどうでしょうか?
AnsiString(CP932)
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
A |
B |
∵ |
∵ |
∵ |
C |
D |
0x41 |
0x42 |
0x81 |
0xE6 |
0x87 |
0xFA |
0x5B |
0xA4 |
0x43 |
0x44 |
// Unicode 版 Delphi での例
type
SJISString = type AnsiString(932);
var
A: SJISString;
procedure ShowBinary(S: RawByteString);
var
i: Integer;
Dmy: RawByteString;
begin
Dmy := #$0D#$0A;
for i:=1 to Length(S) do
begin
Dmy := Dmy + AnsiStrings.Format('%.2x', [Ord(S[i])]);
if i < Length(S) then
Dmy := Dmy + ',';
end;
ShowMessage(S + Dmy);
end;
begin
// AnsiRightStr
A := 'A';
A := A + 'B';
A := A + #$81#$E6;
A := A + #$87#$9A;
A := A + #$FA#$5B;
A := A + 'C';
A := A + 'D';
A := StrUtils.AnsiRightStr(A, 5);
ShowBinary(A); // #$81#$E6 #$81#$E6 #$81#$E6 #$43 #$44 (NG)
// MecsRightStr
A := 'A';
A := A + 'B';
A := A + #$81#$E6;
A := A + #$87#$9A;
A := A + #$FA#$5B;
A := A + 'C';
A := A + 'D';
A := MecsRightStr(A, 5);
ShowBinary(A); // #$81#$E6 #$87#$9A #$FA#$5B #$43 #$44
end;
|
// ANSI 版 Delphi での例
var
A: AnsiString;
procedure ShowBinary(S: AnsiString);
var
i: Integer;
Dmy: AnsiString;
begin
Dmy := #$0D#$0A;
for i:=1 to Length(S) do
begin
Dmy := Dmy + Format('%.2x', [Ord(S[i])]);
if i < Length(S) then
Dmy := Dmy + ',';
end;
ShowMessage(S + Dmy);
end;
begin
// AnsiRightStr
A := 'AB' + #$81#$E6 + #$87#$9A + #$FA#$5B + 'CD';
A := AnsiRightStr(A, 5);
ShowBinary(A); // #$81#$E6 #$81#$E6 #$81#$E6 #$43 #$44 (NG)
// MecsRightStr
A := 'AB' + #$81#$E6 + #$87#$9A + #$FA#$5B + 'CD';
A := MecsRightStr(A, 5, 932);
ShowBinary(A); // #$81#$E6 #$87#$9A #$FA#$5B #$43 #$44
end;
|
AnsiRightStr の AnsiString 版は内部で WideString/UnicodeString へ変換してから文字列操作を行い、結果を AnsiString で返します。そのため、ラウンドトリップ変換を行う事になり、CP932 の"字形が同じで別のコードポイントの文字"は Unicode の一つのコードポイントにまとめられてしまいます。
UnicodeString / WideString
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
A |
B |
𠮷 |
野 |
屋 |
C |
D |
0x0041 |
0x0042 |
0xD842 |
0xDFB7 |
0x91CE |
0x5C4B |
0x0043 |
0x0044 |
// Unicode 版 Delphi での例
var
U: UnicodeString;
Idx: Integer;
begin
// RightStr
U := 'AB' + #$20BB7 + '野屋CD';
U := RightStr(U, 5); // 野屋CD (サロゲートペアが考慮されない)
ShowMessage(U);
// AnsiRightStr
U := 'AB' + #$20BB7 + '野屋CD';
U := AnsiRightStr(U, 5); // 野屋CD (サロゲートペアが考慮されない)
ShowMessage(U);
// MecsRightStr
U := 'AB' + #$20BB7 + '野屋CD';
U := MecsRightStr(U, 5); // 𠮷野屋CD
ShowMessage(U);
end;
|
// ANSI 版 Delphi での例
// (通常、ShowMessage ではサロゲートペアを表示できない)
var
W: WideString;
Idx: Integer;
begin
// RightStr
W := 'AB' + #$D842#$DFB7 + '野屋CD';
W := RightStr(W, 5);
ShowMessage(W); // ?野屋CD (サロゲートペアが考慮されない)
// AnsiRightStr
W := 'AB' + #$D842#$DFB7 + '野屋CD';
W := AnsiRightStr(W, 5); // ?野屋CD (サロゲートペアが考慮されない)
ShowMessage(W);
// MecsRightStr
W := 'AB' + #$D842#$DFB7 + '野屋CD';
W := MecsRightStr(W, 5); // 𠮷野屋
ShowMessage(W);
end;
|
UTF8String(CP_UTF8/CP65001)
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
A |
B |
𠮷 |
野 |
屋 |
C |
D |
0x41 |
0x42 |
0xF0 |
0xA0 |
0xAE |
0xB7 |
0xE9 |
0x87 |
0x8E |
0xE5 |
0xB1 |
0x8B |
0x43 |
0x44 |
// Unicode 版 Delphi での例
var
U8: UTF8String;
Idx: Integer;
procedure ShowBinary(S: RawByteString);
var
i: Integer;
Dmy: RawByteString;
begin
Dmy := #$0D#$0A;
for i:=1 to Length(S) do
begin
Dmy := Dmy + AnsiStrings.Format('%.2x', [Ord(S[i])]);
if i < Length(S) then
Dmy := Dmy + ',';
end;
ShowMessage(S + Dmy);
end;
begin
// RightStr
U8 := 'AB' + #$20BB7 + '野屋CD';
U8 := StrUtils.RightStr(U8, 5); // #$E3#$83#$BB#$EF#$BD#$AE#$43#$44 (NG)
ShowBinary(U8);
// AnsiRightStr
U8 := 'AB' + #$20BB7 + '野屋CD';
U8 := AnsiStrings.AnsiRightStr(U8, 5); // #$3F#$E9#$87#$8E#$E5#$B1#$8B#$43#$44 (NG)
ShowBinary(U8);
// MecsRightStr
U8 := 'AB' + #$20BB7 + '野屋CD';
U8 := MecsRightStr(U8, 5); // #$F0#$A0#$AE#$B7 #$E9#$87#$8E #$E5#$B1#$8B #$43 #$44
ShowBinary(U8);
end;
|
// ANSI 版 Delphi での例
// (通常、ShowMessage ではサロゲートペアを表示できない)
var
U8: UTF8String;
Idx: Integer;
procedure ShowBinary(S: AnsiString);
var
i: Integer;
Dmy: AnsiString;
begin
Dmy := #$0D#$0A;
for i:=1 to Length(S) do
begin
Dmy := Dmy + Format('%.2x', [Ord(S[i])]);
if i < Length(S) then
Dmy := Dmy + ',';
end;
ShowMessage(S + Dmy);
end;
begin
// RightStr
U8 := 'AB' + #$F0#$A0#$AE#$B7 + #$E9#$87#$8E + #$E5#$B1#$8B + 'CD';
U8 := RightStr(U8, 5); // #$E5#$B1#$8B#$43#$44 (NG)
ShowBinary(U8);
// AnsiRightStr
U8 := 'AB' + #$F0#$A0#$AE#$B7 + #$E9#$87#$8E + #$E5#$B1#$8B + 'CD';
U8 := AnsiRightStr(U8, 5); // #$E9#$87#$8E#$E5#$B1#$8B#$43#$44 (NG)
ShowBinary(U8);
// MecsRightStr
U8 := 'AB' + #$F0#$A0#$AE#$B7 + #$E9#$87#$8E + #$E5#$B1#$8B + 'CD';
U8 := MecsRightStr(U8, 5, CP_UTF8); // #$F0#$A0#$AE#$B7 #$E9#$87#$8E #$E5#$B1#$8B #$43 #$44
ShowBinary(U8);
end;
|
関連情報:
MecsStrCharLength 関数は文字の長さをエレメント数で返します。
分野の指定
Common ルーチン
Unicode 版 Delphi の構文:
function MecsStrCharLength(const Str: PAnsiChar; CodePage: DWORD = 0): Integer;
function MecsStrCharLength(const Str: PUnicodeChar): Integer;
ANSI 版 Delphi の構文:
function MecsStrCharLength(const Str: PAnsiChar; CodePage: DWORD = 0): Integer;
function MecsStrCharLength(const Str: PWideChar): Integer;
説明:
MecsStrCharLength 関数は、Str の最初の文字のサイズをエレメント単位で返します。
PAnsiChar 版を使う際には CodePage を設定し、コードページを強制すべきです。何故なら、Unicode 版 Delphi であっても PAnsiChar(が指す先の文字列) のコードページを自動的に知る事はできないからです。
RTL の StrCharLength に相当する機能です。
関連情報:
MecsStrConv 関数は指定に従って変換された文字列を返します。
分野の指定
Common ルーチン
Unicode 版 Delphi の構文:
function MecsStrConv(const str: UnicodeString; Conversion: DWORD; Optional: LCID = 0): UnicodeString;
function MecsStrConv(const str: AnsiString; Conversion: DWORD; Optional: LCID = 0): AnsiString;
ANSI 版 Delphi の構文:
function MecsStrConv(const str: WideString; Conversion: DWORD; Optional: LCID = 0): WideString;
function MecsStrConv(const str: AnsiString; Conversion: DWORD; Optional: LCID = 0): AnsiString;
説明:
MecsStrConv 関数は指定に従って変換された文字列を返します。例えば次のようなコードで、入力された文字列中に含まれる全角カタカナを全角ひらがなへ変換できます。
procedure TForm1.Button1Click(Sender: TObject);
begin
Edit2.Text := MecsStrConv(Edit1.Text, LCMAP_HIRAGANA);
end;
|
Conversion には、LCMAPString() API の dwMapFlags に渡す定数を用いる事ができます。
LCMAP_BYTEREV |
バイト順序を反転します。 |
LCMAP_FULLWIDTH |
全角文字にします |
LCMAP_HALFWIDTH |
半角文字にします |
LCMAP_HIRAGANA |
ひらがなにします |
LCMAP_KATAKANA |
カタカナにします |
LCMAP_LINGUISTIC_CASING |
大文字と小文字の区別に、ファイルシステムの規則(既定値)ではなく、言語上の規則を使います。 |
LCMAP_LOWERCASE |
小文字を使います。 |
LCMAP_SIMPLIFIED_CHINESE |
中国語の簡体字を繁体字にマップします。 |
LCMAP_SORTKEY |
正規化されたワイド文字並び替えキーを作成します。 |
LCMAP_TRADITIONAL_CHINESE |
中国語の繁体字を簡体字にマップします。 |
LCMAP_UPPERCASE |
大文字を使います。 |
NORM_IGNORECASE |
大文字と小文字を区別しません。 |
NORM_IGNOREKANATYPE |
ひらがなとカタカナを区別しません。ひらがなとカタカナを同じと見なします。 |
NORM_IGNORENONSPACE |
送りなし文字を無視します。このフラグをセットすると、日本語アクセント文字も削除されます。 |
NORM_IGNORESYMBOLS |
記号を無視します。 |
NORM_IGNOREWIDTH |
シングルバイト文字と、ダブルバイトの同じ文字とを区別しません。 |
SORT_STRINGSORT |
区切り記号を記号と同じものとして扱います。 |
また、Optional にロケールID を指定する事もできます。Optional を省略した場合にはデフォルトのロケールが使われます。
関連情報:
MecsStrElementType 関数は文字列が 1 エレメントで 1 文字のエレメント, 2 エレメントで 1 文字の場合の最初のエレメント, 2 番目以降のエレメントのいずれであるかを示します。
分野の指定
Common ルーチン
Unicode 版 Delphi の構文:
function MecsStrElementType(const Str: PAnsiChar; Index: Cardinal; CodePage: DWORD = 0): TElementType;
function MecsStrElementType(const Str: PUnicodeChar; Index: Cardinal): TElementType;
ANSI 版 Delphi の構文:
function MecsStrElementType(const Str: PAnsiChar; Index: Cardinal; CodePage: DWORD = 0): TElementType;
function MecsStrElementType(const Str: PWideChar; Index: Cardinal): TElementType;
説明:
MecsStrElementType 関数を呼び出すと、Index パラメータで指定されるエレメントの種類がわかります。Index は、0 が文字列 Str の最初のエレメントを指定し、1 が 2 番目のエレメントを指定するといった具合になります。
PAnsiChar 版において、マルチバイト文字セット (MBCS) を使わない環境では、ElementType は必ず etSingle を返します。それ以外の場合、ElementType は、指定されたエレメント (バイト) が完全な 1 文字を表すときに etSingle、2 バイト文字の最初のバイトを表すときに etLead、マルチバイト文字の 2 番目のバイトを表すときに etTrail を返します。
PUnicodeChar / PWideChar 版において、サロゲートペアを使わない環境では、ElementType は必ず etSingle を返します。それ以外の場合、ElementType は、指定されたエレメント (ワード) が完全な 1 文字を表すときに etSingle、サロゲートペアの最初のワードを表すときに etLead、サロゲートペアの 2 番目のワードを表すときに etTrail を返します。
etSingle |
1 つのエレメントで構成される文字。 |
etLead |
2 つ以上のエレメントで構成される文字の最初のエレメント。 |
etTrail |
2 つ以上のエレメントで構成される文字の2 つ目以降のエレメント。 |
PAnsiChar 版を使う際には CodePage を設定し、コードページを強制すべきです。何故なら、Unicode 版 Delphi であっても PAnsiChar(が指す先の文字列) のコードページを自動的に知る事はできないからです。
RTL の StrByteType に相当する機能です。
メモ:
Index が Str の長さを超えないようにするためのチェックは行われません。開発者側の操作で Index を範囲内に収めてください。
関連情報:
MecsStrLen 関数は文字列内のヌルターミネータを除いた文字数を返します。
分野の指定
Common ルーチン
Unicode 版 Delphi の構文:
function MecsStrLen(const Str: PAnsiChar; CodePage: DWORD = 0): Cardinal;
function MecsStrLen(const Str: PUnicodeChar): Cardinal;
ANSI 版 Delphi の構文:
function MecsStrLen(const Str: PAnsiChar; CodePage: DWORD = 0): Cardinal;
function MecsStrLen(const Str: PWideChar): Cardinal;
説明:
MecsStrLen 関数は文字列内のヌルターミネータを除いた文字数を返します。
PAnsiChar 版を使う際には CodePage を設定し、コードページを強制すべきです。何故なら、Unicode 版 Delphi であっても PAnsiChar(が指す先の文字列) のコードページを自動的に知る事はできないからです。
RTL の StrLen に相当する機能です。マルチバイト文字 / サロゲートペア が考慮されます。
関連情報:
MecsStrNextChar 関数は次の文字を指すポインタを返します。
分野の指定
Common ルーチン
Unicode 版 Delphi の構文:
function MecsStrNextChar(const Str: PAnsiChar; CodePage: DWORD = 0): PAnsiChar;
function MecsStrNextChar(const Str: PUnicodeChar): PUnicodeChar;
ANSI 版 Delphi の構文:
function MecsStrNextChar(const Str: PAnsiChar; CodePage: DWORD = 0): PAnsiChar;
function MecsStrNextChar(const Str: PWideChar): PWideChar;
説明:
MecsStrNextChar 関数は、Str の 2 番目の文字を指すポインタを返します。
PAnsiChar 版を使う際には CodePage を設定し、コードページを強制すべきです。何故なら、Unicode 版 Delphi であっても PAnsiChar(が指す先の文字列) のコードページを自動的に知る事はできないからです。
RTL の StrNextChar に相当する機能です。
関連情報:
MecsCCSLength 関数は文字で使われるエレメント数を返します。
分野の指定
結合文字列 ルーチン
Unicode 版 Delphi の構文:
function MecsCCSLength(const S: UnicodeString; Index: Integer): Integer;
function MecsCCSLength(const S: WideString; Index: Integer): Integer;
ANSI 版 Delphi の構文:
function MecsCCSLength(const S: WideString; Index: Integer): Integer;
説明:
MecsCCSLength 関数を呼び出すと、S の Index 位置にある文字のサイズがエレメント単位でわかります。エレメントは文字を構成する要素で、UnicodeString / WideString なら WideChar となります。
サンプルコード:
UnicodeString / WideString
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
0x0041 |
0x0042 |
0xD842 |
0xDFB7 |
0x91CE |
0x5C4B |
0x304B |
0x3099 |
0x0043 |
0x0044 |
U+0041 |
U+0042 |
U+20BB7 |
U+91CE |
U+5C4B |
U+304B |
U+3099 |
U+0043 |
U+0044 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
A |
B |
𠮷 |
野 |
屋 |
か |
゙ |
C |
D |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
A |
B |
𠮷 |
野 |
屋 |
が |
C |
D |
// Unicode 版 Delphi での例
var
U: UnicodeString;
Idx: Integer;
begin
U := 'AB' + #$20BB7 + '野屋' + #$304B#$3099 + 'CD';
Idx := MecsCCSLength(U, 2); // 1
ShowMessage(IntToStr(Idx));
Idx := MecsCCSLength(U, 3); // 2
ShowMessage(IntToStr(Idx));
Idx := MecsCCSLength(U, 6); // 2
ShowMessage(IntToStr(Idx));
end;
|
// ANSI / Unicode 版 Delphi 共通 の例
var
W: WideString;
Idx: Integer;
begin
W := 'AB' + #$D842#$DFB7 + '野屋' + #$304B#$3099 + 'CD';
Idx := MecsCCSLength(W, 2); // 1
ShowMessage(IntToStr(Idx));
Idx := MecsCCSLength(W, 3); // 2
ShowMessage(IntToStr(Idx));
Idx := MecsCCSLength(W, 6); // 2
ShowMessage(IntToStr(Idx));
end;
|
MecsCharLength の結合文字列対応版です。
MecsCCSToElementIndex 関数は文字列内の指定された文字の最初のエレメントを 1 から始まるインデックスで返します。
分野の指定
結合文字列 ルーチン
Unicode 版 Delphi の構文:
function MecsCCSToElementIndex(const S: UnicodeString; Index: Integer): Integer;
function MecsCCSToElementIndex(const S: WideString; Index: Integer): Integer;
ANSI 版 Delphi の構文:
function MecsCCSToElementIndex(const S: WideString; Index: Integer): Integer;
説明:
MecsCCSToElementIndex 関数を呼び出すと、文字列 S の指定された位置にある文字のエレメントオフセットを取得できます。1 は最初の文字、2 は 2 番目の文字を指定します。
MecsCCSToElementIndex は、Index が範囲外の場合 (Index <= 0 または S の文字数が Index より小さい) にゼロを返します。Index パラメータが サロゲートペア や 結合文字列 を示す場合、
MecsCCSToElementIndex は最初のエレメントのオフセットを返します。
端的に言えば、MecsCCSToElementIndex は文字インデックスから、文字の先頭に位置するエレメントのインデックスを取得する関数です。
サンプルコード:
UnicodeString / WideString
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
0x0041 |
0x0042 |
0xD842 |
0xDFB7 |
0x91CE |
0x5C4B |
0x304B |
0x3099 |
0x0043 |
0x0044 |
U+0041 |
U+0042 |
U+20BB7 |
U+91CE |
U+5C4B |
U+304B |
U+3099 |
U+0043 |
U+0044 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
A |
B |
𠮷 |
野 |
屋 |
か |
゙ |
C |
D |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
A |
B |
𠮷 |
野 |
屋 |
が |
C |
D |
// Unicode 版 Delphi での例
var
U: UnicodeString;
Idx: Integer;
begin
U := 'AB' + #$20BB7 + '野屋' + #$304B#$3099 + 'CD';
Idx := MecsCCSToElementIndex(U, 2); // 2
ShowMessage(IntToStr(Idx));
Idx := MecsCCSToElementIndex(U, 3); // 3
ShowMessage(IntToStr(Idx));
Idx := MecsCCSToElementIndex(U, 6); // 7
ShowMessage(IntToStr(Idx));
end;
|
// ANSI / Unicode 版 Delphi 共通 の例
var
W: WideString;
Idx: Integer;
begin
W := 'AB' + #$D842#$DFB7 + '野屋' + #$304B#$3099 + 'CD';
Idx := MecsCCSToElementIndex(W, 2); // 2
ShowMessage(IntToStr(Idx));
Idx := MecsCCSToElementIndex(W, 3); // 3
ShowMessage(IntToStr(Idx));
Idx := MecsCCSToElementIndex(W, 6); // 7
ShowMessage(IntToStr(Idx));
end;
|
MecsCharToElementIndex の結合文字列対応版です。
MecsCCSToElementLen 関数は文字列の最初の MaxLen の文字の長さをエレメント数で返します。
分野の指定
結合文字列 ルーチン
Unicode 版 Delphi の構文:
function MecsCCSToElementLen(const S: UnicodeString; MaxLen: Integer): Integer;
function MecsCCSToElementLen(const S: WideString; MaxLen: Integer): Integer;
ANSI 版 Delphi の構文:
function MecsCCSToElementLen(const S: WideString; MaxLen: Integer): Integer;
説明:
MecsCCSToElementLen 関数を呼び出すと、文字列の文字単位の長さをそれに対応するエレメント単位の長さに変換できます。MecsCCSToElementLen は、S の最初の MaxLen 数の文字で必要なエレメント数を返します。S が MaxLen より小さい場合、CharToByteLen は S の長さをエレメント数で返します。
端的に言えば、MecsCCSToElementLen は文字インデックスから、文字の最後に位置するエレメントのインデックス...つまり、文字単位で考えて"キリのいいエレメント数"を取得する関数です。エレメントを文字単位で区切って処理する際に利用します。
サンプルコード:
UnicodeString / WideString
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
0x0041 |
0x0042 |
0xD842 |
0xDFB7 |
0x91CE |
0x5C4B |
0x304B |
0x3099 |
0x0043 |
0x0044 |
U+0041 |
U+0042 |
U+20BB7 |
U+91CE |
U+5C4B |
U+304B |
U+3099 |
U+0043 |
U+0044 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
A |
B |
𠮷 |
野 |
屋 |
か |
゙ |
C |
D |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
A |
B |
𠮷 |
野 |
屋 |
が |
C |
D |
// Unicode 版 Delphi での例
var
U: UnicodeString;
Idx: Integer;
begin
U := 'AB' + #$20BB7 + '野屋' + #$304B#$3099 + 'CD';
Idx := MecsCCSToElementLen(U, 2); // 2
ShowMessage(IntToStr(Idx));
Idx := MecsCCSToElementLen(U, 4); // 3
ShowMessage(IntToStr(Idx));
Idx := MecsCCSToElementLen(U, 8); // 7
ShowMessage(IntToStr(Idx));
end;
|
// ANSI / Unicode 版 共通 の例
var
W: WideString;
Idx: Integer;
begin
W := 'AB' + #$D842#$DFB7 + '野屋' + #$304B#$3099 + 'CD';
Idx := MecsCCSToElementLen(W, 2); // 2
ShowMessage(IntToStr(Idx));
Idx := MecsCCSToElementLen(W, 4); // 3
ShowMessage(IntToStr(Idx));
Idx := MecsCCSToElementLen(W, 8); // 7
ShowMessage(IntToStr(Idx));
end;
|
MecsCharToElementLen の結合文字列対応版です。
MecsCombiningType 関数は文字が 基底文字 / 結合文字 のどちらであるかを判断します。
分野の指定
結合文字列 ルーチン
Delphi の構文:
function MecsCombiningType(U: UCS4Char): TCombiningType;
説明:
MecsCombiningType 関数は U に指定した Unicode コードポイントで表される文字が 基底文字 / 結合文字 のどちらであるかを判断します。戻り値は以下のようになります。
ctBase |
基底文字 |
ctCombining |
結合文字 |
MecsCopyC 関数は文字列の部分文字列を返します。
分野の指定
結合文字列 ルーチン
Unicode 版 Delphi の構文:
function MecsCopyC(const S: UnicodeString; Index, Count: Integer): UnicodeString;
function MecsCopyC(const S: WideString; Index, Count: Integer): WideString;
ANSI 版 Delphi の構文:
function MecsCopyC(const S: WideString; Index, Count: Integer): WideString;
説明:
MecsCopyC 関数は文字列の部分文字列を返します。S は、文字列型の式です。Index と Count は整数型の式です。MecsCopyC 関数は、S の Index 文字目から Count 個の文字の入った部分文字列を返します。
Index が S より長い場合、MecsCopyC は空の文字列を返します。コピーできる文字より多い値が Count に指定されている場合、S の Index 文字目 から S の終わりまでの文字が返されます。
動的配列はサポートしません。MecsCopy の結合文字列対応版です。
MecsDeleteC 手続きは文字列から部分文字列を削除します。
分野の指定
結合文字列 ルーチン
Unicode 版 Delphi の構文:
procedure MecsDeleteC(var S: UnicodeString; Index, Count: Integer);
procedure MecsDeleteC(var S: WideString; Index, Count: Integer);
ANSI 版 Delphi の構文:
procedure MecsDeleteC(var S: WideString; Index, Count: Integer);
説明:
MecsDeleteC 手続きは、文字列 S の Index 文字目から始まる Count 個の文字の部分文字列を削除します。S は文字列型の変数です。Index と Count は整数型の式です。
index が文字列の長さより大きい場合、または 1 未満の場合は、削除は行われません。
Count が index 以降の文字数より大きい場合、MecsDeleteC は終わりまでのすべての文字を削除します。count が 0 以下の場合は、削除は行われません。
MecsDelete の結合文字列対応版です。
MecsElementToCCSIndex 関数は文字列内の指定されたエレメントを含む文字の位置を返します。
分野の指定
結合文字列 ルーチン
Unicode 版 Delphi の構文:
function MecsElementToCCSIndex(const S: UnicodeString; Index: Integer): Integer;
function MecsElementToCCSIndex(const S: WideString; Index: Integer): Integer;
ANSI 版 Delphi の構文:
function MecsElementToCCSIndex(const S: WideString; Index: Integer): Integer;
説明:
MecsElementToCCSIndex 関数を呼び出すと、文字列内で特定のエレメントを含んでいる文字がわかります。1 は最初のエレメント、2 は 2 番目のエレメントを指定します。Index パラメータが 文字列変数にないエレメントを指定する場合 (Index < 0 または Index > Length(S)) 、MecsElementToCCSIndex は 0 を返します。
端的に言えば、MecsElementToCCSIndex はエレメントインデックスから、そのエレメントを含む文字のインデックスを返す関数です。
サンプルコード:
UnicodeString / WideString
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
0x0041 |
0x0042 |
0xD842 |
0xDFB7 |
0x91CE |
0x5C4B |
0x304B |
0x3099 |
0x0043 |
0x0044 |
U+0041 |
U+0042 |
U+20BB7 |
U+91CE |
U+5C4B |
U+304B |
U+3099 |
U+0043 |
U+0044 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
A |
B |
𠮷 |
野 |
屋 |
か |
゙ |
C |
D |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
A |
B |
𠮷 |
野 |
屋 |
が |
C |
D |
// Unicode 版 Delphi での例
var
U: UnicodeString;
Idx: Integer;
begin
U := 'AB' + #$20BB7 + '野屋' + #$304B#$3099 + 'CD';
Idx := MecsElementToCCSIndex(U, 2); // 2
ShowMessage(IntToStr(Idx));
Idx := MecsElementToCCSIndex(U, 4); // 3
ShowMessage(IntToStr(Idx));
Idx := MecsElementToCCSIndex(U, 8); // 6
ShowMessage(IntToStr(Idx));
end;
|
// ANSI / Unicode 版 共通の例
var
W: WideString;
Idx: Integer;
begin
W := 'AB' + #$D842#$DFB7 + '野屋' + #$304B#$3099 + 'CD';
Idx := MecsElementToCCSIndex(W, 2); // 2
ShowMessage(IntToStr(Idx));
Idx := MecsElementToCCSIndex(W, 4); // 3
ShowMessage(IntToStr(Idx));
Idx := MecsElementToCCSIndex(W, 8); // 6
ShowMessage(IntToStr(Idx));
end;
|
MecsElementToCharIndex の結合文字列対応版です。
MecsElementToCCSLen 関数は文字列の最初の MaxLen エレメントに含まれている文字数を返します。
分野の指定
結合文字列 ルーチン
Unicode 版 Delphi の構文:
function MecsElementToCCSLen(const S: UnicodeString; MaxLen: Integer): Integer;
function MecsElementToCCSLen(const S: WideString; MaxLen: Integer): Integer;
ANSI 版 Delphi の構文:
function MecsElementToCCSLen(const S: WideString; MaxLen: Integer): Integer;
説明:
MecsElementToCCSLen 関数を呼び出すと、文字列の部分的な文字数がわかります。MecsElementToCCSLen は MaxLen エレメントまたは文字列の最後のどちらか先に達する方までの文字数をカウントします。
端的に言えば、MecsElementToCCSLen はエレメントインデックスから文字列長を返す関数です。
サンプルコード:
UnicodeString / WideString
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
0x0041 |
0x0042 |
0xD842 |
0xDFB7 |
0x91CE |
0x5C4B |
0x304B |
0x3099 |
0x0043 |
0x0044 |
U+0041 |
U+0042 |
U+20BB7 |
U+91CE |
U+5C4B |
U+304B |
U+3099 |
U+0043 |
U+0044 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
A |
B |
𠮷 |
野 |
屋 |
か |
゙ |
C |
D |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
A |
B |
𠮷 |
野 |
屋 |
が |
C |
D |
// Unicode 版 Delphi での例
var
U: UnicodeString;
Idx: Integer;
begin
U := 'AB' + #$20BB7 + '野屋' + #$304B#$3099 + 'CD';
Idx := MecsElementToCCSLen(U, 2); // 2
ShowMessage(IntToStr(Idx));
Idx := MecsElementToCCSLen(U, 3); // 3
ShowMessage(IntToStr(Idx));
Idx := MecsElementToCCSLen(U, 7); // 6
ShowMessage(IntToStr(Idx));
end;
|
// ANSI / Unicode 版 共通の例
var
W: WideString;
Idx: Integer;
begin
W := 'AB' + #$D842#$DFB7 + '野屋' + #$304B#$3099 + 'CD';
Idx := MecsElementToCCSLen(W, 2); // 2
ShowMessage(IntToStr(Idx));
Idx := MecsElementToCCSLen(W, 3); // 3
ShowMessage(IntToStr(Idx));
Idx := MecsElementToCCSLen(W, 7); // 6
ShowMessage(IntToStr(Idx));
end;
|
MecsElementToCharLen の結合文字列対応版です。
MecsInsertC 手続きは部分文字列を文字列の指定された位置に挿入します。
分野の指定
結合文字列 ルーチン
Unicode 版 Delphi の構文:
procedure MecsInsertC(const Source: UnicodeString; var S: UnicodeString; Index: Integer);
procedure MecsInsertC(const Source: WideString; var S: WideString; Index: Integer);
ANSI 版 Delphi の構文:
procedure MecsInsertC(const Source: WideString; var S: WideString; Index: Integer);
説明:
MecsInsertC 手続きは Source を S に index 文字目の位置から挿入します。
Source は文字列型の式です。S は任意の長さの文字列型の変数です。Index は整数型の式です。Index は文字インデックスです。
Index が 1 未満の場合、Index は 1 にマップされます。Index が文字列の最後を過ぎている場合、Index は文字列の長さに設定され、操作が追加に変わります。
Source パラメータが空の文字列の場合、Insert は何もしません
MecsInsert の結合文字列対応版です。
MecsLeftStrC 関数は文字列の最初に表示される指定された長さの部分文字列を返します。
分野の指定
結合文字列 ルーチン
Unicode 版 Delphi の構文:
function MecsLeftStrC(const AText: UnicodeString; const ACount: Integer): UnicodeString;
function MecsLeftStrC(const AText: WideString; const ACount: Integer): WideString;
ANSI 版 Delphi の構文:
function MecsLeftStrC(const AText: WideString; const ACount: Integer): WideString;
説明:
MecsLeftStrC 関数は、AText の先頭から ACount で指定された文字数以内の文字数を返します。
サンプルコード:
UnicodeString / WideString
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
0x0041 |
0x0042 |
0xD842 |
0xDFB7 |
0x91CE |
0x5C4B |
0x304B |
0x3099 |
0x0043 |
0x0044 |
U+0041 |
U+0042 |
U+20BB7 |
U+91CE |
U+5C4B |
U+304B |
U+3099 |
U+0043 |
U+0044 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
A |
B |
𠮷 |
野 |
屋 |
か |
゙ |
C |
D |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
A |
B |
𠮷 |
野 |
屋 |
が |
C |
D |
// Unicode 版 Delphi での例
var
U: UnicodeString;
Idx: Integer;
begin
// LeftStr
U := 'AB' + #$20BB7 + '野屋' + #$304B#$3099 + 'CD';
U := LeftStr(U, 6);
ShowMessage(U); // AB𠮷野屋
// MecsLeftStr
U := 'AB' + #$20BB7 + '野屋' + #$304B#$3099 + 'CD';
U := MecsLeftStr(U, 6);
ShowMessage(U); // AB𠮷野屋か
// MecsLeftStrC
U := 'AB' + #$20BB7 + '野屋' + #$304B#$3099 + 'CD';
U := MecsLeftStrC(U, 6);
ShowMessage(U); // AB𠮷野屋が
end;
|
// ANSI / Unicode 版 共通の例
var
W: WideString;
Idx: Integer;
begin
// LeftStr
W := 'AB' + #$D842#$DFB7 + '野屋' + #$304B#$3099 + 'CD';
W := LeftStr(W, 6);
ShowMessage(W); // AB𠮷野屋
// MecsLeftStr
W := 'AB' + #$D842#$DFB7 + '野屋' + #$304B#$3099 + 'CD';
W := MecsLeftStr(W, 6);
ShowMessage(W); // AB𠮷野屋か
// MecsLeftStrC
W := 'AB' + #$D842#$DFB7 + '野屋' + #$304B#$3099 + 'CD';
W := MecsLeftStrC(W, 6);
ShowMessage(W); // AB𠮷野屋が
end;
|
MecsLeftStr の結合文字列対応版です。
MecsLengthC 関数は文字列内の文字数を返します
分野の指定
結合文字列 ルーチン
Unicode 版 Delphi の構文:
function MecsLengthC(const S: UnicodeString): Integer;
function MecsLengthC(const S: WideString): Integer;
ANSI 版 Delphi の構文:
function MecsLengthC(const S: WideString): Integer;
説明:
MecsLengthC 関数は文字列内の文字数を返します。動的配列はサポートされません。
MecsLength の結合文字列対応版です。
MecsMidStrC 関数は文字列内の指定された部分に表示される、指定された長さの部分文字列を返します。
分野の指定
結合文字列 ルーチン
Unicode 版 Delphi の構文:
function MecsMidStrC(const AText: UnicodeString; const AStart, ACount: Integer): UnicodeString;
function MecsMidStrC(const AText: WideString; const AStart, ACount: Integer): WideString;
ANSI 版 Delphi の構文:
function MecsMidStrC(const AText: WideString; const AStart, ACount: Integer): WideString;
説明:
MecsMidStrC は、AText の AStart 文字目から Count プロパティで指定した文字数の部分文字列を返します。
もし AStart が AText 文字列の長さよりも大きい場合、MidStr 関数は空文字列を返します。
Count が有効な文字数以上の値を指定している場合は、AText の AStart 文字目から AText の最後までの文字のみが返されます。
サンプルコード:
UnicodeString / WideString
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
0x0041 |
0x0042 |
0xD842 |
0xDFB7 |
0x91CE |
0x5C4B |
0x304B |
0x3099 |
0x0043 |
0x0044 |
U+0041 |
U+0042 |
U+20BB7 |
U+91CE |
U+5C4B |
U+304B |
U+3099 |
U+0043 |
U+0044 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
A |
B |
𠮷 |
野 |
屋 |
か |
゙ |
C |
D |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
A |
B |
𠮷 |
野 |
屋 |
が |
C |
D |
// Unicode 版 Delphi での例
var
U: UnicodeString;
Idx: Integer;
begin
// MidStr
U := 'AB' + #$20BB7 + '野屋' + #$304B#$3099 + 'CD';
U := MidStr(U, 3, 4);
ShowMessage(U); // 𠮷野屋
// MecsMidStr
U := 'AB' + #$20BB7 + '野屋' + #$304B#$3099 + 'CD';
U := MecsMidStr(U, 3, 4);
ShowMessage(U); // 𠮷野屋か
// MecsMidStrC
U := 'AB' + #$20BB7 + '野屋' + #$304B#$3099 + 'CD';
U := MecsMidStrC(U, 3, 4);
ShowMessage(U); // 𠮷野屋が
end;
|
// ANSI / Unicode 版 共通の例
var
W: WideString;
Idx: Integer;
begin
// MidStr
W := 'AB' + #$20BB7 + '野屋' + #$304B#$3099 + 'CD';
W := MidStr(W, 3, 4);
ShowMessage(W); // 𠮷野屋
// MecsMidStr
W := 'AB' + #$20BB7 + '野屋' + #$304B#$3099 + 'CD';
W := MecsMidStr(W, 3, 4);
ShowMessage(W); // 𠮷野屋か
// MecsMidStrC
W := 'AB' + #$20BB7 + '野屋' + #$304B#$3099 + 'CD';
W := MecsMidStrC(W, 3, 4);
ShowMessage(W); // 𠮷野屋が
end;
|
MecsMidStr の結合文字列対応版です。
MecsNextCCSIndex 関数は次の文字のエレメントインデックスを返します。
分野の指定
結合文字列 ルーチン
Unicode 版 Delphi の構文:
function MecsNextCCSIndex(const S: UnicodeString; Index: Integer): Integer;
function MecsNextCCSIndex(const S: WideString; Index: Integer): Integer;
ANSI 版 Delphi の構文:
function MecsNextCCSIndex(const S: WideString; Index: Integer): Integer;
説明:
MecsNextCCSIndex は、Index 文字目から始まる文字に続く文字の最初のエレメントのエレメントインデックスを返します。
MecsNextCharIndex の結合文字列対応版です。
MecsReverseStringC 関数は指定した文字列の向きを逆にしたものを返します。
分野の指定
結合文字列 ルーチン
Unicode 版 Delphi の構文:
function MecsReverseStringC(const AText: UnicodeString): UnicodeString;
function MecsReverseStringC(const AText: WideString): WideString;
ANSI 版 Delphi の構文:
function MecsReverseStringC(const AText: WideString): WideString;
説明:
MecsReverseStringC 関数は、AText で指定した値の文字を逆向きに配置したものを返します。
MecsReverseString の結合文字列対応版です。
MecsRightStrC 関数は文字列の最後に表示される指定された長さの部分文字列を返します。
分野の指定
結合文字列 ルーチン
Unicode 版 Delphi の構文:
function MecsRightStrC(const AText: UnicodeString; const ACount: Integer): UnicodeString;
function MecsRightStrC(const AText: WideString; const ACount: Integer): WideString;
ANSI 版 Delphi の構文:
function MecsRightStrC(const AText: WideString; const ACount: Integer): WideString;
説明:
MecsRightStrC 関数は、AText の末尾から ACount 以内の文字数を返します。
サンプルコード:
UnicodeString / WideString
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
0x0041 |
0x0042 |
0xD842 |
0xDFB7 |
0x91CE |
0x5C4B |
0x304B |
0x3099 |
0x0043 |
0x0044 |
U+0041 |
U+0042 |
U+20BB7 |
U+91CE |
U+5C4B |
U+304B |
U+3099 |
U+0043 |
U+0044 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
A |
B |
𠮷 |
野 |
屋 |
か |
゙ |
C |
D |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
A |
B |
𠮷 |
野 |
屋 |
が |
C |
D |
// Unicode 版 Delphi での例
var
U: UnicodeString;
Idx: Integer;
begin
// RightStr
U := 'AB' + #$20BB7 + '野屋' + #$304B#$3099 + 'CD';
U := RightStr(U, 6);
ShowMessage(U); // 野屋がCD
// MecsRightStr
U := 'AB' + #$20BB7 + '野屋' + #$304B#$3099 + 'CD';
U := MecsRightStr(U, 6);
ShowMessage(U); // 野屋がCD
// MecsRightStrC
U := 'AB' + #$20BB7 + '野屋' + #$304B#$3099 + 'CD';
U := MecsRightStrC(U, 6);
ShowMessage(U); // 𠮷野屋がCD
end;
|
// Unicode 版 Delphi での例
var
U: UnicodeString;
Idx: Integer;
begin
// RightStr
U := 'AB' + #$20BB7 + '野屋' + #$304B#$3099 + 'CD';
U := RightStr(U, 6);
ShowMessage(U); // 野屋がCD
// MecsRightStr
U := 'AB' + #$20BB7 + '野屋' + #$304B#$3099 + 'CD';
U := MecsRightStr(U, 6);
ShowMessage(U); // 野屋がCD
// MecsRightStrC
U := 'AB' + #$20BB7 + '野屋' + #$304B#$3099 + 'CD';
U := MecsRightStrC(U, 6);
ShowMessage(U); // 𠮷野屋がCD
end;
|
MecsRightStr の結合文字列対応版です。
MecsStrCCSLength 関数は文字の長さをエレメント数で返します。
分野の指定
結合文字列 ルーチン
Unicode 版 Delphi の構文:
function MecsStrCCSLength(const Str: PUnicodeChar): Integer;
ANSI 版 Delphi の構文:
function MecsStrCCSLength(const Str: PWideChar): Integer;
説明:
MecsStrCCSLength 関数は、Str の最初の文字のサイズをエレメント単位で返します。
MecsStrCharLength の結合文字列対応版です。
MecsStrLenC 関数は文字列内のヌルターミネータを除いた文字数を返します。
分野の指定
結合文字列 ルーチン
Unicode 版 Delphi の構文:
function MecsStrLenC(const Str: PUnicodeChar): Cardinal;
ANSI 版 Delphi の構文:
function MecsStrLenC(const Str: PWideChar): Cardinal;
説明:
MecsStrLenC 関数は文字列内のヌルターミネータを除いた文字数を返します。
MecsStrLen の結合文字列対応版です。
MecsStrNextCCS 関数は次の文字を指すポインタを返します。
分野の指定
結合文字列 ルーチン
Unicode 版 Delphi の構文:
function MecsStrNextCCS(const Str: PUnicodeChar): PUnicodeChar;
ANSI 版 Delphi の構文:
function MecsStrNextCCS(const Str: PWideChar): PWideChar;
説明:
MecsStrNextCCS 関数は、Str の 2 番目の文字を指すポインタを返します。
MecsStrNextChar の結合文字列対応版です。
AnsiToUTF32 関数は Ansi 文字列を UTF-32 に変換します。
分野の指定
Convert ルーチン
Unicode 版 Delphi の構文:
function AnsiToUTF32(const AText: RawByteString; CodePage: DWORD = 0): UCS4String;
function AnsiToUTF32(const AText: RawByteString): UCS4String;
ANSI 版 Delphi の構文:
function AnsiToUTF32(const AText: AnsiString; CodePage: DWORD = 0): UCS4String;
function AnsiToUTF32(const AText: AnsiString): UCS4String;
説明:
AnsiToUTF32 関数は Ansi 文字列を UTF-32 に変換します。
CodePage を指定することで、コードページを強制する事ができます。コードページを指定しなかった場合には、Unicode 版 Delphi の場合には AnsiString のコードページ、ANSI 版 Delphi の場合には MECSUtils.DefaultAnsiCodePage 変数に設定されたコードページ (デフォルトでは規定のコードページ) が使われます。
関連情報:
AnsiToUTF16 関数は Ansi 文字列を UTF-16 (Unicode) に変換します。
分野の指定
Convert ルーチン
Unicode 版 Delphi の構文:
function AnsiToUTF16(const AText: RawByteString): WideString;
ANSI 版 Delphi の構文:
function AnsiToUTF16(const AText: AnsiString): WideString;
説明:
AnsiToUTF16 関数は Ansi 文字列を UTF-16 (Unicode) に変換します。
CodePage を指定することで、コードページを強制する事ができます。コードページを指定しなかった場合には、Unicode 版 Delphi の場合には AnsiString のコードページ、ANSI 版 Delphi の場合には MECSUtils.DefaultAnsiCodePage 変数に設定されたコードページ (デフォルトでは規定のコードページ) が使われます。
関連情報:
AnsiToUTF8 関数は Ansi 文字列を UTF-8 に変換します。
分野の指定
Convert ルーチン
Unicode 版 Delphi の構文:
function AnsiToUTF8(const AText: RawByteString; CodePage: DWORD = 0): UTF8String;
ANSI 版 Delphi の構文:
function AnsiToUTF8(const AText: AnsiString; CodePage: DWORD = 0): UTF8String;
説明:
AnsiToUTF8 関数は Ansi 文字列を UTF-8 に変換します。
CodePage を指定することで、コードページを強制する事ができます。コードページを指定しなかった場合には、Unicode 版 Delphi の場合には AnsiString のコードページ、ANSI 版 Delphi の場合には MECSUtils.DefaultAnsiCodePage 変数に設定されたコードページ (デフォルトでは規定のコードページ) が使われます。
RTL の AnsiToUtf8 に相当する機能です。
関連情報:
CodePointToUTF16 関数は Unicode のコードポイントから UTF-16 (Unicode) へ変換します。
分野の指定
Convert ルーチン
Delphi の構文:
function CodePointToUTF16(const CodePoint: UCS4Char): WideString;
説明:
CodePointToUTF16 関数は Unicode のコードポイントから UTF-16 (Unicode) へ変換します。
関連情報:
CodePointToUTF8 関数は Unicode のコードポイントから UTF-8 へ変換します。
分野の指定
Convert ルーチン
Unicode 版 Delphi の構文:
function CodePointToUTF8(const CodePoint: UCS4Char): RawByteString;
ANSI 版 Delphi の構文:
function CodePointToUTF8(const CodePoint: UCS4Char): UTF8String;
説明:
CodePointToUTF8 関数は Unicode のコードポイントから UTF-8 へ変換します。
関連情報:
ConvertMultiByteToUnicode 関数は Ansi 文字列を Unicode (UTF-16) へ変換します。
分野の指定
Convert ルーチン
Unicode 版 Delphi の構文:
function ConvertMultiByteToUnicode(SrcCodePage: DWORD; const SrcStr: RawByteString; var DstStr: WideString): Boolean;
ANSI 版 Delphi の構文:
function ConvertMultiByteToUnicode(SrcCodePage: DWORD; const SrcStr: AnsiString; var DstStr: WideString): Boolean;
説明:
ConvertMultiByteToUnicode 関数は Ansi 文字列を Unicode (UTF-16) へ変換します。
AnsiToUTF16 との違いについてですが、
// Unicode 版 Delphi での例
var
SL: TStringList;
Enc: TEncoding;
begin
SL := TstringList.Create;
Enc := TEncoding.GetEncoding(51932);
try
SL.LoadFromFile('C:\CP51932.TXT', Enc);
ShowMessage(SL.Text);
finally
Enc.Free;
SL.Free;
end;
end;
|
このコードは "コードページが不正" のエラーが出て、CP51932 (EUC-JP) を変換できませんが、
// Unicode 版 Delphi での例
var
FS: TFileStream;
EUC: RawByteString;
S: WideString;
r: Integer;
begin
FS := TFileStream.Create('C:\CP51932.TXT', fmOpenRead);
try
SetLength(EUC, FS.Size);
FS.ReadBuffer(PAnsiChar(EUC)^, FS.Size);
if ConvertMultiByteToUnicode(51932, EUC, S) then
ShowMessage(S);
finally
FS.Free;
end;
end;
|
ConvertUnicodeToMultiByte() を使えば、CP51932 (EUC-JP) を利用する事が可能です。
関連情報:
ConvertString 関数は Ansi 文字列を他のコードページの Ansi へ変換します。
分野の指定
Convert ルーチン
Unicode 版 Delphi の構文:
function ConvertString(SrcCodePage, DstCodePage: DWORD; const SrcStr: RawByteString; var DstStr: RawByteString): Boolean;
ANSI 版 Delphi の構文:
function ConvertString(SrcCodePage, DstCodePage: DWORD; const SrcStr: AnsiString; var DstStr: AnsiString): Boolean;
説明:
ConvertString 関数は Ansi 文字列を他のコードページの Ansi へ変換します。他方の Ansi コードページに存在しない文字は失われるか、代替文字で置換される可能性があります。
関連情報:
ConvertUnicodeToMultiByte 関数は Unicode (UTF-16) 文字列を Ansi へ変換します。
分野の指定
Convert ルーチン
Unicode 版 Delphi の構文:
function ConvertUnicodeToMultiByte(DstCodePage: DWORD; const SrcStr: WideString; var DstStr: RawByteString): Boolean;
ANSI 版 Delphi の構文:
function ConvertUnicodeToMultiByte(DstCodePage: DWORD; const SrcStr: WideString; var DstStr: AnsiString): Boolean;
説明:
ConvertUnicodeToMultiByte 関数は Unicode (UTF-16) 文字列を Ansi へ変換します。Unicode に存在し、Ansi に存在しない文字は失われます。
UTF16ToAnsi との違いについてですが、
// Unicode 版 Delphi での例
var
SL: TStringList;
Enc: TEncoding;
begin
SL := TstringList.Create;
Enc := TEncoding.GetEncoding(51932);
try
SL.Text := 'あいうえお';
SL.SaveToFile('C:\CP51932.TXT', Enc);
finally
Enc.Free;
SL.Free;
end;
end;
|
このコードは "コードページが不正" のエラーが出て、CP51932 (EUC-JP) を変換できませんが、
// Unicode 版 Delphi での例
var
FS: TFileStream;
EUC: RawbyteString;
begin
if ConvertUnicodeToMultiByte(51932, 'あいうえお' , EUC) then
begin
FS := TFileStream.Create('C:\CP51932.TXT', fmCreate);
try
FS.WriteBuffer(PAnsiChar(EUC)^, Length(EUC));
finally
FS.Free;
end;
end;
end;
|
ConvertUnicodeToMultiByte() を使えば、CP51932 (EUC-JP) を利用する事が可能です。
関連情報:
TrimNullTerm 手続きは文字列末尾の Null 文字を除去します。
分野の指定
Convert ルーチン
Delphi構文:
procedure TrimNullTerm(var S: UCS4String);
procedure TrimNullTerm(var S: WideString);
procedure TrimNullTerm(var S: TBytes);
説明:
TrimNullTerm 手続きは文字列末尾の Null 文字を除去します。TrimRight() と違い、Null 文字のみを除去します。
関連情報:
UTF32ToAnsi 関数は UTF-32 文字列を Ansi へ変換します。
分野の指定
Convert ルーチン
Unicode 版 Delphi の構文:
function UTF32ToAnsi(const UCS4Text: UCS4String; CodePage: DWORD = 0): RawByteString;
ANSI 版 Delphi の構文:
function UTF32ToAnsi(const UCS4Text: UCS4String; CodePage: DWORD = 0): AnsiString;
説明:
UTF32ToAnsi 関数は UTF-32 文字列を Ansi へ変換します。Unicode に存在し、Ansi に存在しない文字は失われます。
CodePage を指定することで、コードページを強制する事ができます。コードページを指定しなかった場合には、Unicode 版 Delphi の場合には AnsiString のコードページ、ANSI 版 Delphi の場合には MECSUtils.DefaultAnsiCodePage 変数に設定されたコードページ (デフォルトでは規定のコードページ) が使われます。
関連情報:
UTF32ToUTF16 関数は UTF-32 文字列を UTF-16 (Unicode) へ変換します。
分野の指定
Convert ルーチン
Unicode 版 Delphi の構文:
function UTF32ToUTF16(const UCS4Text: UCS4String): WideString;
説明:
UTF32ToUTF16 関数は UTF-32 文字列を UTF-16 (Unicode) へ変換します。
RTL の UCS4StringToWideString、Unicode 版 Delphi-RTL の UCS4StringToUnicodeString に相当する機能ですが、UCS4StringToWideString と違い、サロゲートペアを正しく処理します。- XE で修正されています
関連情報:
UTF32ToUTF8 関数は UTF-32 文字列を UTF-8 へ変換します。
分野の指定
Convert ルーチン
Unicode 版 Delphi の構文:
function UTF32ToUTF8(const UCS4Text: UCS4String): RawByteString;
ANSI 版 Delphi の構文:
function UTF32ToUTF8(const UCS4Text: UCS4String): UTF8String;
説明:
UTF32ToUTF8 関数は UTF-32 文字列を UTF-8 へ変換します。
関連情報:
UTF16ToAnsi 関数は UTF-16 (Unicode) 文字列を Ansi へ変換します。
分野の指定
Convert ルーチン
Unicode 版 Delphi の構文:
function UTF16ToAnsi(const WText: WideString; CodePage: DWORD = 0): RawByteString;
ANSI 版 Delphi の構文:
function UTF16ToAnsi(const WText: WideString; CodePage: DWORD = 0): AnsiString;
説明:
UTF16ToAnsi 関数は UTF-16 (Unicode) 文字列を Ansi へ変換します。Unicode に存在し、Ansi に存在しない文字は失われます。
CodePage を指定することで、コードページを強制する事ができます。コードページを指定しなかった場合には、Unicode 版 Delphi の場合には AnsiString のコードページ、ANSI 版 Delphi の場合には MECSUtils.DefaultAnsiCodePage 変数に設定されたコードページ (デフォルトでは規定のコードページ) が使われます。
注意:
Windows 2000 で ISO-2022 系の文字エンコーディングを処理する場合、Delphi の RTL では文字列の欠損が発生します。これは Windows 2000 の WideCharToMultibyte() のバグに起因するもので、Unicode 版 Delphi の代入による暗黙の文字コード変換等も影響を受けます。
関連情報:
UTF16ToUTF32 関数は UTF-16 (Unicode) 文字列を UTF-32 へ変換します。
分野の指定
Convert ルーチン
Delphi の構文:
function UTF16ToUTF32(const WText: WideString): UCS4String;
説明:
UTF16ToUTF32 関数は UTF-16 (Unicode) 文字列を UTF-32 へ変換します。
RTL の WideStringToUCS4String、Unicode 版 Delphi-RTL の UnicodeStringToUCS4String に相当する機能ですが、WideStringToUCS4String と違い、サロゲートペアを正しく処理します。- XE で修正されています
関連情報:
UTF16ToUTF8 関数は UTF-16 (Unicode) 文字列を UTF-8 へ変換します。
分野の指定
Convert ルーチン
Unicode 版 Delphi の構文:
function UTF16ToUTF8(const WText: WideString): RawByteString;
ANSI 版 Delphi の構文:
function UTF16ToUTF8(const WText: WideString): UTF8String;
説明:
UTF16ToUTF8 関数は UTF-16 (Unicode) 文字列を UTF-8 へ変換します。
RTL の UTF8Encode に相当する機能ですが、ANSI 版 Delphi 版の UTF8Encode と違い、4 バイト文字 (サロゲートペア) を正しく処理します。
関連情報:
UTF8ToAnsi 関数は UTF-8 文字列を Ansi へ変換します。
分野の指定
Convert ルーチン
Unicode 版 Delphi の構文:
function UTF8ToAnsi(const UCF8Text: RawByteString; CodePage: DWORD = 0): RawByteString;
ANSI 版 Delphi の構文:
function UTF8ToAnsi(const UCF8Text: UTF8String; CodePage: DWORD = 0): AnsiString;
説明:
UTF8ToAnsi 関数は UTF-8 文字列を Ansi へ変換します。Unicode に存在し、Ansi に存在しない文字は失われます。
CodePage を指定することで、コードページを強制する事ができます。コードページを指定しなかった場合には、Unicode 版 Delphi の場合には AnsiString のコードページ、ANSI 版 Delphi の場合には MECSUtils.DefaultAnsiCodePage 変数に設定されたコードページ (デフォルトでは規定のコードページ) が使われます。
RTL の Utf8ToAnsi に相当する機能です。
関連情報:
UTF8ToUTF32 関数は UTF-8 文字列を UTF-32 へ変換します。
分野の指定
Convert ルーチン
Unicode 版 Delphi の構文:
function UTF8ToUTF32(const UCF8Text: RawByteString): UCS4String;
ANSI 版 Delphi の構文:
function UTF8ToUTF32(const UCF8Text: UTF8String): UCS4String;
説明:
UTF8ToUTF32 関数は UTF-8 文字列を UTF-32 へ変換します。
関連情報:
UTF8ToUTF16 関数は UTF-8 文字列を UTF-16 (Unicode) へ変換します。
分野の指定
Convert ルーチン
Unicode 版 Delphi の構文:
function UTF8ToUTF16(const UCF8Text: RawByteString): WideString;
ANSI 版 Delphi の構文:
function UTF8ToUTF16(const UCF8Text: UTF8String): WideString;
説明:
UTF8ToUTF16 関数は UTF-8 文字列を UTF-16 (Unicode) へ変換します。
RTL の UTF8Decode に相当する機能ですが、ANSI 版 Delphi 版の UTF8Decode と違い、4 バイト文字 (サロゲートペア) を正しく処理します。
関連情報:
MecsCodepageToCharset 関数は Windows コードページを Charset 名に変換します。
分野の指定
HTML ルーチン
Unicode 版 Delphi の構文:
function MecsCodePageToCharset(const CodePage: WORD): UnicodeString;
ANSI 版 Delphi の構文:
function MecsCodePageToCharset(const CodePage: WORD): WideString;
説明:
MecsCodepageToCharset 関数は Windows コードページを Charset 名に変換します。例えば、Codepage に 1252 を渡すと、'iso-8859-1' という文字列を返します。
関連情報:
MecsCharsetToCodepage 関数は Charset 名を Windows コードページに変換します。
分野の指定
HTML ルーチン
Unicode 版 Delphi の構文:
function MecsCharsetToCodepage(const Charset: UnicodeString): WORD;
ANSI 版 Delphi の構文:
function MecsCharsetToCodepage(const Charset: WideString): WORD;
説明:
MecsCharsetToCodepage 関数は Charset 名を Windows コードページに変換します。例えば、Charset に 'iso-8859-1' を渡すと、1252 を返します。
Indy の TIdCharsets.CharsetToCodepage() とケースバイケースで使い分けて下さい。
関連情報:
MecsHTMLDecode 関数は文字列中の HTML 文字実体参照 (& / > / < / ") / 数値文字参照 (
進値; / 進値;) を実際の文字に変換します。
分野の指定
HTML ルーチン
Unicode 版 Delphi の構文:
function MecsHTMLDecode(const s: UnicodeString): UnicodeString;
ANSI 版 Delphi の構文:
function MecsHTMLDecode(const s: WideString): WideString;
説明:
MecsHTMLDecode 関数は文字列中の HTML 文字実体参照 (& / > / < / ") あるいは、数値文字参照 (
進値; / 進値;) を実際の文字に変換します。
RTL の HttpApp.HTMLDecode とは異なり、サロゲートペアを正しく処理します。 - XE2 で修正されています
関連情報:
MecsHTMLEncode 関数は文字列中の & > < " を HTML 文字実体参照に変換し、BMP 範囲外の文字を数値文字参照へ変換します。
分野の指定
HTML ルーチン
Unicode 版 Delphi の構文:
function MecsHTMLEncode(const s: UnicodeString): UnicodeString;
ANSI 版 Delphi の構文:
function MecsHTMLEncode(const s: WideString): WideString;
説明:
MecsHTMLEncode 関数は文字列中の & > < " を HTML 文字実体参照に変換し、BMP 範囲外の文字を 16 進数表現の数値文字参照へ変換します。- XE2 Update 1 で修正されています
関連情報:
MECSUtils の関数/手続きのうち、UCS4String / TBytes に対して出力するものについては、末尾にヌル文字が付くためエレメント数が +1 になる事があります。
このため、RTL の Length() 等で文字数をカウントすると、意図しないエレメント数になる事があります。
UCS4String / TBytes の実体は動的配列になっており、本来はヌル終端で処理しなくてもいいのですが、これらを文字列ポインタでキャストして処理しやすいようにとの配慮からです。
動的配列の後には、暗黙的にヌル文字が含まれますが、古い Delphi では、暗黙的なヌル文字が保証されません。このため、動的配列の最初の要素を文字列ポインタに渡して処理しようとすると、古い Delphi では文字列の後に不正な文字が続く事になってしまいます。
UCS4String を PUCS4Char、TBytes を PAnsiChar で処理するのを容易にするために、末尾にヌル文字が付加されます。UCS4String をポインタで処理する事はまずないとは思いますが、ライブラリとしての一貫性を持たせるために動的配列が実体の変数に対しては等しく末尾にヌル文字が付加されます。
なお、WideString は動的配列と同様の動作をしますが、BSTR 互換という事もあり、末尾の暗黙的なヌル文字が保証されています。
バイト列/ワード列のバイナリ操作が目的であれば末尾にヌル文字が付くという仕様は不自然だと思いますが、MECSUtils の目的は '文字列操作' にありますのでこのような仕様となっております。ご了承下さい。