当前位置: 首页 > 编程语言 > C#

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

时间:2023-04-10 13:46:08 C#

如何反转包含代理对的字符串我写了这个方法来反转字符串publicstringReverse(strings){if(string.IsNullOrEmpty(s))return;TextElementEnumerator枚举器=StringInfo.GetTextElementEnumerator(s);变种元素=新列表();while(enumerator.MoveNext()){varcs=enumerator.GetTextElement().ToCharArray();如果(cs.Length>1){elements.AddRange(cs.Reverse());}else{elements.AddRange(cs);}}elements.Reverse();返回string.Concat(元素);现在,我不想开始讨论如何使我的代码更高效或如何使用一个而不是我的代码。我知道您可以执行Xors和其他各种操作来改进此代码。如果我以后想重构代码,我可以很容易地做到,因为我有单元测试。目前,这可以正确地反转BML字符串(包括带有重音符号的字符串,如"LesMisérables""LesMiseu0301rables")和包含组合字符的字符串,如"LesMisérables"。我的测试包含代理对,如果它们像这样表达的话Assert.AreEqual("𠈓",_stringOperations.Reverse("𠈓"));但是如果我像这样表达代理对Assert.AreEqual("u10000",_stringOperations.Reverse("u10000"));然后测试失败。是否有支持代理对的密封实现?如果我在上面犯了任何错误,请指出,因为我不是Unicode专家。u10000是由两个字符组成的字符串:?(Unicode代码点1000)后跟一个0(可以通过检查方法中s的值来检测)。如果反转两个字符,它们将不再匹配输入。看起来你在Unicode字符'LINEARBSYLLABLEB008A'(U+10000)之后,十六进制代码点为10000。来自MSDN上的Unicode字符转义序列:uhexhexhexdigithexdigitUhexdigithexhexdigithexdigithexhexdigithexdigithexnumbers所以你必须使用四位或八位数字。使用U00010000(注意大写U)或uD800uDC00而不是u10000。死灵法术。发生这种情况是因为您使用List.Reverse而不是List.Reverse//usingSystem.Globalization;TextElementEnumeratorenumerator=StringInfo.GetTextElementEnumerator("LesMiseu0301rables");列表元素=newList();while(enumerator.MoveNext())elements.Add(enumerator.GetTextElement());元素.Reverse();字符串反转=string.Concat(元素);//selbarésiMseL有关详细信息,请参阅JonSkeet的小马视频:https:///vimeo.com/7403673以下是正确反转字符串(字符串,而不是字符序列)的方法:publicstaticclassTest{privatestaticSystem.Collections.Generic.ListGraphemeClusters(strings){System.Collections.Generic。列表ls=newSystem.Collections.Generic.List();System.Globalization.TextElementEnumerator枚举器=System.Globalization.StringInfo.GetTextElementEnumerator(s);while(enumerator.MoveNext()){ls.Add((string)enumerator.Current);}返回ls;}//这个私有静态字符串ReverseGraphemeClusters(strings){if(string.IsNullOrEmpty(s)||s.Length==1)returns;系统.集合。Generic.Listls=GraphemeClusters(s);ls.Reverse();返回string.Join("",ls.ToArray());}publicstaticvoidTestMe(){strings="LesMiseu0301rables";字符串r=ReverseGraphemeClusters(s);//这是错误的://char[]a=s.ToCharArray();//System.Array.Reverse(a);//字符串r=新字符串(a);.WriteLine(r);请注意,您需要知道之间的区别-一个字符和一个字形-一个字节(8位)和一个代码点/符文(32位)-一个代码点和一个GraphemeCluster[32+位](又名Grapheme/Glyph)参考:角色是一个重载的术语,可以表示很多东西代码点是信息的原始单位。文本是一系列代码点。每个代码点都是一个由Unicode标准分配的数字。字素是一个或多个代码点的序列,这些代码点显示为单个图形单元,读者将其识别为书写系统的单个元素。例如,a和?都是字形,但它们可能由多个代码点组成(例如,?可能是两个代码点,一个用于基本字符a,后跟一个用于分音符;但也有另一种选择,legacy,a表示此字形点的单个代码)。某些代码点永远不会是任何字形的一部分(例如,零宽度非连接器或方向覆盖)。字形是一种图像,通常存储在字体(字形集合)中,代表一个字形或其部分。字体可以将多个字形组合成一个表示,例如如果上面的?是单个代码点,字体可能会选择将其呈现为两个独立的、空间重叠的字形。对于OTF,字体的GSUB和GPOS表包含替换和定位信息以使其正常工作。字体还可以包含同一字素的多个替代字形。这是一个开始。它可能不是最快的,但它似乎可以满足我们的要求。内部静态字符串ReverseItWithSurrogate(stringstringToReverse){stringresult=string.Empty;//我们要先把字符串放到字符数组中char[]stringArray=stringToReverse.ToCharArray();//这是将保存反转字符串的对象。varsb=newStringBuilder();boolhaveSurrogate=false;//我们从后面开始查看每个字符。如果它是一个//低代理项并且先验者是一个高而不是=0;loopVariable--){//如果低代理是索引0,我们不能检查高代理if(loopVariable>0){haveSurrogate=false;if(char.IsLowSurrogate(stringArray[loopVariable])&&char.IsHighSurrogate(stringArray[loopVariable-1])){sb.Append(stringArray[loopVariable-1]);sb.Append(stringArray[loopVariable]);//并强制第二个字符从我们的循环中删除loopVariable--;有代理=真;}if(!haveSurrogate){sb.Append(stringArray[loopVariable]);}}else{//否现在我们必须处理列表中的第一项,如果它不是高代理项的话。如果(!haveSurrogate){sb.Append(stringArray[loopVariable]);}}}结果=sb.ToString();最好不要在Chrome中查看!以上就是C#学习教程:如何反转包含代理对的字符串共享的全部内容。如果对大家有用,需要详细了解C#学习教程,希望大家多多关注——usingSystem.Linq;使用系统。使用System.Globalization;使用系统诊断;使用系统集合;命名空间OrisNumbers{publicstaticclassIEnumeratorExtensions{publicstaticIEnumerableAsIEnumerable(thisIEnumeratoriterator){while(iterator.MoveNextld()){yiereturn(T)iterator.Current;}}}classProgram{staticvoidMain(string[]args){vars="foo𝌆barma?anama?ana";Debug.WriteLine(s);Debug.WriteLine(string.Join("",StringInfo.GetTextElementEnumerator(s.Normalize()).AsIEnumerable().Reverse()));控制台.Read();}}}本文收集自网络,不代表立场。如涉及侵权,请右击联系管理员删除。如需转载请注明出处: