【问题标题】:string.IndexOf() not recognizing modified charactersstring.IndexOf() 无法识别修改后的字符
【发布时间】:2013-10-21 13:49:52
【问题描述】:

当使用IndexOf 查找一个字符后跟一个大值字符(例如 char 700 是 ʼ)时,IndexOf 无法识别您要查找的字符。

例如

string find = "abcʼabcabc";   
int index = find.IndexOf("c");

在这段代码中,索引应该是 2,但它返回 6。

有没有办法解决这个问题?

【问题讨论】:

  • 这工作int index = find.IndexOf("c", StringComparison.Ordinal);

标签: c# indexof


【解决方案1】:

Unicode 字母 700 是 modifier apostrophe:换句话说,它修改了字母 c。同样,如果您要使用“e”后跟character 769 (0x301),它就不再是“e”了:e 已被修改为带有重音的e。即:é。您会看到该字母实际上是两个字符:将其复制到记事本并按退格键(很简洁,嗯?)。

您需要在不进行任何语言比较的情况下进行“序数”比较(逐字节)。这将找到“c”,并忽略它被下一个字母修改的语言事实。在我的“e”示例中,字节为 (65)(769),因此如果您逐字节查找 65,您会找到它,这忽略了 (65)(769) 在语言上是同(233):é。如果您从语言上搜索 (233),它将找到“等效”(65)(769):

string find = "abéabcabc";
int index = find.IndexOf("é"); //gives you '2' even though the "find" has two characters and the the "indexof" is one

希望这不会太令人困惑。如果您在实际代码中执行此操作,则应在 cmets 中准确解释您在做什么:就像在我的“e”示例中一般,您希望对用户数据进行语义等价,并为例如常量(希望不会像这样不同,以免你的successor hunt you down with an axe)。

【讨论】:

  • 或者你可以告诉 indexOf 寻找字符:int index = find.IndexOf('c');
  • 啊,好点子。那是面试中的一个恶作剧问题:IndexOf('c')IndexOf("c") 有什么区别?
【解决方案2】:

构造在语言上与简单字节不同。使用 Ordinal 字符串比较来强制进行字节比较。

        string find = "abcʼabcabc";

        int index = find.IndexOf("c", StringComparison.Ordinal);

【讨论】:

  • +1 为澄清起见,Ordinal 排序规则有效,因为它根据字符串中每个 Char 的数值(Unicode 代码点)执行比较 - 请参阅 docs,正是 OP 的要求。
  • 或者只使用find.IndexOf('c') 而不是提供字符串。
  • StringComparison.Ordinal 会让代码变慢吗?
  • 没有。但是,如果您担心,请进行测试。过早的优化是万恶之源。
  • @puser 不,事实上它应该在技术上更快
猜你喜欢
  • 2017-12-18
  • 2011-06-25
  • 1970-01-01
  • 2021-08-13
  • 1970-01-01
  • 2015-12-20
  • 2014-03-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多