私は最終的に使用しましたLCMapStringEx
が、私にとってはうまく機能します。これは (の任意のセット) に基づいていませんCompareOptions
が、CompareInfo.GetSortKey ドキュメントは私を に導くLCMapString
ため、正規化された文字列の my の効果は、ここで呼ばれるハードコードされた を使用してindexOf
と同じ結果をもたらすはずです:CultureInfo.CompareInfo.IndexOf
CompareOptions
dwMapFlags
public static string Canonicalize(string src)
{
string localeName = "ja-JP";
string nResult = src;
int nLen, nSize;
uint dwMapFlags = LCMAP_LOWERCASE | LCMAP_HIRAGANA | LCMAP_FULLWIDTH;
IntPtr ptr, pZero = IntPtr.Zero;
nLen = src.Length;
nSize = LCMapStringEx(localeName, dwMapFlags, src, nLen, IntPtr.Zero, 0, pZero, pZero, pZero);
if (nSize > 0)
{
nSize = nSize * sizeof(char);
ptr = Marshal.AllocHGlobal(nSize);
try
{
nSize = LCMapStringEx(localeName, dwMapFlags, src, nLen, ptr, nSize, pZero, pZero, pZero);
if (nSize > 0) nResult = Marshal.PtrToStringUni(ptr, nSize);
}
finally
{
Marshal.FreeHGlobal(ptr);
}
}
return nResult;
}
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
static extern int LCMapStringEx(
string lpLocaleName,
uint dwMapFlags,
string lpSrcStr,
int cchSrc,
[Out]
IntPtr lpDestStr,
int cchDest,
IntPtr lpVersionInformation,
IntPtr lpReserved,
IntPtr sortHandle);
private const uint LCMAP_LOWERCASE = 0x100;
private const uint LCMAP_UPPERCASE = 0x200;
private const uint LCMAP_SORTKEY = 0x400;
private const uint LCMAP_BYTEREV = 0x800;
private const uint LCMAP_HIRAGANA = 0x100000;
private const uint LCMAP_KATAKANA = 0x200000;
private const uint LCMAP_HALFWIDTH = 0x400000;
private const uint LCMAP_FULLWIDTH = 0x800000;
また、動作するMicrosoft.VisualBasic.StrConvも試しましたが、 pinvoking の 2 倍の速度ですLCMapStringEx
。