Что такое безопасная реплика Юникода для String.IndexOf (строковый ввод), которая может обрабатывать суррогатные пары? - PullRequest
0 голосов
/ 04 мая 2018

Я пытаюсь найти эквивалент C # string.IndexOf(string), который может обрабатывать суррогатные пары в символах Юникода.

Я могу получить индекс при сравнении только отдельных символов, как в коде ниже:

    public static int UnicodeIndexOf(this string input, string find)
    {
        return input.ToTextElements().ToList().IndexOf(find);
    }

    public static IEnumerable<string> ToTextElements(this string input)
    {
        var e = StringInfo.GetTextElementEnumerator(input);
        while (e.MoveNext())
        {
            yield return e.GetTextElement();
        }
    }

Но если я попытаюсь использовать строку в качестве переменной find, она не будет работать, потому что каждый текстовый элемент содержит только один символ для сравнения.

Есть какие-нибудь предложения относительно того, как написать это?

Спасибо за любую помощь.

EDIT:

Ниже приведен пример того, почему это необходимо:

код

 Console.WriteLine("HolyCow?BUBBYY?YY?Y".IndexOf("BUBB"));
 Console.WriteLine("HolyCow@BUBBYY@YY@Y".IndexOf("BUBB"));

OUTPUT

9
8

Обратите внимание, где я заменяю символ ? на @, значения меняются.

1 Ответ

0 голосов
/ 05 мая 2018

Вы в основном хотите найти индекс одного строкового массива в другом строковом массиве. Мы можем адаптировать код из этого вопроса для этого:

public static class Extensions {
    public static int UnicodeIndexOf(this string input, string find, StringComparison comparison = StringComparison.CurrentCulture) {
        return IndexOf(
           // split input by code points
           input.ToTextElements().ToArray(),
           // split searched value by code points
           find.ToTextElements().ToArray(), 
           comparison);
    }
    // code from another answer
    private static int IndexOf(string[] haystack, string[] needle, StringComparison comparision) {
        var len = needle.Length;
        var limit = haystack.Length - len;
        for (var i = 0; i <= limit; i++) {
            var k = 0;
            for (; k < len; k++) {
                if (!String.Equals(needle[k], haystack[i + k], comparision)) break;
            }

            if (k == len) return i;
        }

        return -1;
    }

    public static IEnumerable<string> ToTextElements(this string input) {
        var e = StringInfo.GetTextElementEnumerator(input);
        while (e.MoveNext()) {
            yield return e.GetTextElement();
        }
    }
}
...