【问题标题】:What is a Unicode safe replica of String.IndexOf(string input) that can handle Surrogate Pairs?什么是可以处理代理对的 String.IndexOf(string input) 的 Unicode 安全副本?
【发布时间】:2018-10-15 09:05:16
【问题描述】:

我正在尝试找出一个等效于 C#string.IndexOf(string) 的方法,它可以处理 Unicode 字符中的代理对。

仅比较单个字符时我能够获取索引,如下面的代码所示:

    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 变量,那么它将不起作用,因为每个文本元素只包含一个要比较的字符。

关于如何写这篇文章有什么建议吗?

感谢所有帮助。

编辑:

以下是为什么需要这样做的示例:

代码

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

输出

9
8

请注意,我将 ???? 字符替换为 @ 时,值会发生变化。

【问题讨论】:

  • 对两个字符串使用相同的编码,你很好
  • @Steve 我在我的问题中添加了一些信息。这些字符串是相同的编码还是有区别?
  • @Ibrennan208,从您的初始实现看来,您正试图找到一个 single 字形,因为您在位于效果TextElements,但从您的示例数据看来,您实际上想要找到长度> 1 字形的子字符串的索引。您能具体说明您正在寻求哪种解决方案吗? (只需在您的测试数据上运行您的代码 - 它不会工作 - indexOf 将返回 -1)
  • @ironstone13 我想找到长度 > 1 的子字符串的索引。在问题中,我解释说,如果我只是将字符串与单个字符进行比较,我可以让它工作,但我想要扩展它以允许用户输入多字符串来查找索引。

标签: c# string unicode indexof surrogate-pairs


【解决方案1】:

你基本上想在另一个字符串数组中找到一个字符串数组的索引。我们可以为此修改this问题的代码:

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();
        }
    }
}

【讨论】:

  • 很好,我写的是一样的,但你更快!
  • 谢谢,这正是我要找的!
猜你喜欢
  • 2018-10-15
  • 2015-01-25
  • 1970-01-01
  • 1970-01-01
  • 2013-12-15
  • 1970-01-01
  • 2015-11-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多