我编写了以下代码片段以消除文本块中的过多空格
int index = text.IndexOf(" ");
while (index > 0)
{
text = text.Replace(" ", " ");
index = text.IndexOf(" ");
}
一般来说,这种方法很好,虽然相当原始,但可能效率低下。
当文本包含“ - ”表示某些bizzare原因时indexOf会返回一个匹配项! 替换功能不会移除任何东西,然后它会卡在无限循环中。
有关string.IndexOf的所有想法吗?
答案 0 :(得分:20)
你最有可能在那里,但在SO上发帖时迷路了,是一个“软连字符”。
要重现此问题,我在LINQPad中尝试了此代码:
void Main()
{
var text = "Test1 \u00ad Test2";
int index = text.IndexOf(" ");
while (index > 0)
{
text = text.Replace(" ", " ");
index = text.IndexOf(" ");
}
}
果然,上面的代码只是陷入了循环。
请注意,根据CharMap,\u00ad
是Soft Hyphen的Unicode符号。您也可以随时复制并粘贴CharMap中的字符,但是将其发布到SO上会将其替换为更常见的表兄,连字符号,Unicode符号u002d
(键盘上的那个)。 / p>
您可以阅读String Class文档中的一小部分,其中有关于此主题的内容:
字符串搜索方法(如String.StartsWith和String.IndexOf)也可以执行区分文化或序数字符串比较。以下示例说明了使用IndexOf方法进行序数比较和文化敏感比较之间的差异。文化敏感搜索,其中当前文化是英语(美国)认为子字符串“oe”匹配连字“œ”。 因为软连字符(U + 00AD)是零宽度字符,搜索会将软连字符视为等效于空,并在字符串的开头找到匹配。序数搜索,在另一方面,在任何一种情况下都找不到匹配。
我已经突出了相关部分,但我还记得一篇关于这个确切问题的博客文章,但我的Google-Fu今晚让我失望了。
这里的问题是IndexOf和Replace使用不同的方法来定位文本。
而IndexOf会将软连字符视为“不是真的存在”,从而发现它的每一侧的两个空格为“两个连接的空格”,而Replace方法则不会,因此不会删除任何一个他们。因此,循环存在标准以继续迭代,但由于Replace不会删除符合条件的空格,因此它将永远不会结束。毫无疑问,Unicode符号空间中还有其他类似的字符表现出类似的问题,但这是我见过的最典型的情况。
至少有两种方法可以解决这个问题:
您可以使用Regex.Replace,它似乎没有此问题:
text = Regex.Replace(text, " +", " ");
就个人而言,我可能会使用正则表达式中的空白特殊字符,即\s
,但如果你只想要空格,上面应该可以做到。
您可以明确要求IndexOf使用序数比较,这不会因文本行为而绊倒......好吧......文字:
index = text.IndexOf(" ", StringComparison.Ordinal);