使用IndexOf和CultureInfo 1031的ArgumentOutOfRangeException

isH*_*man 10 c# exception indexof currentculture

string s = "Gewerbegebiet Waldstraße"; //other possible input "Waldstrasse"

int iFoundStart = s.IndexOf("strasse", StringComparison.CurrentCulture);
if (iFoundStart > -1)
    s = s.Remove(iFoundStart, 7);
Run Code Online (Sandbox Code Playgroud)

我正在运行CultureInfo 1031(德语).

IndexOf将'straße'或'strasse'与定义的'strasse'匹配,并返回18作为位置.

删除和替换都没有设置文化的任何重载.

如果我删除6个字符使用删除1字符将保留,如果输入字符串是'strasse'和'straße'将工作.如果输入字符串是'straße'并且我删除了7个字符,则会得到ArgumentOutOfRangeException.

有没有办法安全地删除找到的字符串?提供IndexOf的最后一个索引的任何方法?我更接近IndexOf,它的本机代码正如预期的那样 - 所以没办法做自己的事......

小智 5

本机Win32 API确实公开了找到的字符串的长度.您可以使用P/Invoke FindNLSStringEx直接调用:

static class CompareInfoExtensions
{
    [DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
    private static extern int FindNLSStringEx(string lpLocaleName, uint dwFindNLSStringFlags, string lpStringSource, int cchSource, string lpStringValue, int cchValue, out int pcchFound, IntPtr lpVersionInformation, IntPtr lpReserved, int sortHandle);

    const uint FIND_FROMSTART = 0x00400000;

    public static int IndexOfEx(this CompareInfo compareInfo, string source, string value, int startIndex, int count, CompareOptions options, out int length)
    {
        // Argument validation omitted for brevity
        return FindNLSStringEx(compareInfo.Name, FIND_FROMSTART, source, source.Length, value, value.Length, out length, IntPtr.Zero, IntPtr.Zero, 0);
    }
}

static class Program
{
    static void Main()
    {
        var s = "<<Gewerbegebiet Waldstraße>>";
        //var s = "<<Gewerbegebiet Waldstrasse>>";
        int length;
        int start = new CultureInfo("de-DE").CompareInfo.IndexOfEx(s, "strasse", 0, s.Length, CompareOptions.None, out length);
        Console.WriteLine(s.Substring(0, start) + s.Substring(start + length));
    }
}
Run Code Online (Sandbox Code Playgroud)

我没有看到纯粹使用BCL的方法.