如何反转包含代理项对的字符串

Sac*_*nth 4 c# string reverse utf-16 surrogate-pairs

我已经写了这个方法来反转一个字符串

public string Reverse(string s)
        {
            if(string.IsNullOrEmpty(s)) 
                return s;

            TextElementEnumerator enumerator =
               StringInfo.GetTextElementEnumerator(s);

            var elements = new List<char>();
            while (enumerator.MoveNext())
            {
                var cs = enumerator.GetTextElement().ToCharArray();
                if (cs.Length > 1)
                {
                    elements.AddRange(cs.Reverse());
                }
                else
                {
                    elements.AddRange(cs);
                }
            }

            elements.Reverse();
            return string.Concat(elements);
        }
Run Code Online (Sandbox Code Playgroud)

现在,我不想开始讨论如何提高代码效率或者如何使用一个代替我的代码.我知道你可以执行Xors和各种其他事情来改进这段代码.如果我想稍后重构代码,我可以轻松地完成,因为我有单元测试.

目前,这正确地反转了BML字符串(包括带有重音符号的"Les Misérables"字符串)和包含组合字符的字符串,例如"Les Mise\u0301rables".

我的测试包含代理对,如果它们像这样表达的话

Assert.AreEqual("", _stringOperations.Reverse(""));
Run Code Online (Sandbox Code Playgroud)

但如果我表达这样的代理人对

Assert.AreEqual("\u10000", _stringOperations.Reverse("\u10000"));
Run Code Online (Sandbox Code Playgroud)

然后测试失败了.是否有支持代理对的气密实施?

如果我在上面犯了任何错误,那么请指出这一点,因为我不是Unicode专家.

Cod*_*ter 5

\u10000是一个由两个字符组成的字符串:( ?Unicode代码点1000)后跟一个0(可以通过检查方法中的值来检测s).如果您反转两个字符,它们将不再匹配输入.

看起来你正在使用十六进制代码点10000的Unicode字符'LINEAR B SYLLABLE B008 A'(U + 10000)之后.来自MSDN上的Unicode字符转义序列:

\ u十六进制十六进制十六进制数字十六进制数字

\ U十六进制数字十六进制十六进制数字十六进制数字十六进制十六进制数字十六进制数字十六进制数字

所以你必须使用四位或八位数.

使用\U00010000(注意大写U)或\uD800\uDC00代替\u10000.