ArgumentOutOfRangeException using IndexOf with CultureInfo 1

本文关键字:CultureInfo with IndexOf using ArgumentOutOfRangeException | 更新日期: 2023-09-27 18:20:48

string s = "Gewerbegebiet Waldstraße"; //other possible input "Waldstrasse"
int iFoundStart = s.IndexOf("strasse", StringComparison.CurrentCulture);
if (iFoundStart > -1)
    s = s.Remove(iFoundStart, 7);

我正在运行CultureInfo 1031(德语(。

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

"删除"和"替换"都没有用于设置区域性的过载。

如果我使用 Remove 删除 6 个字符,如果输入字符串是"strasse"并且"straße"将起作用,则将留下 1 个字符。如果输入字符串是"straße"并且我删除了 7 个字符,我会得到 ArgumentOutOfRangeException。

有没有办法安全地删除找到的字符串?有什么方法可以提供 IndexOf 的最后一个索引吗?我更接近 IndexOf 并且正如预期的那样是引擎盖下的本机代码 - 所以没有办法自己做某事......

ArgumentOutOfRangeException using IndexOf with CultureInfo 1

本机 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));
    }
}

我没有看到纯粹使用 BCL 来做到这一点的方法。