我正在处理一些相当低效的C#代码,它们想要删除空白行。它这样做是:如何替换无限循环?
string b; ... while (b.IndexOf("\n\n") >= 0) b = b.Replace ("\n\n", "\n");
单个替换不会与应付(例如)\ n \ n \ n的输入端,因此需要循环。我认为它应该起作用,而且通常都是这样。
但有时它设法进入一个无限循环,我不明白如何。在每次迭代中\ n的数量应该减少,所以它应该最终终止。
任何想法?
我正在处理一些相当低效的C#代码,它们想要删除空白行。它这样做是:如何替换无限循环?
string b; ... while (b.IndexOf("\n\n") >= 0) b = b.Replace ("\n\n", "\n");
单个替换不会与应付(例如)\ n \ n \ n的输入端,因此需要循环。我认为它应该起作用,而且通常都是这样。
但有时它设法进入一个无限循环,我不明白如何。在每次迭代中\ n的数量应该减少,所以它应该最终终止。
任何想法?
将这项工作:
String c = Regex.Replace(b, "\n\n+", "\n");
为什么额外\ n?我在下面发布的答案应该只用\ n +来处理。 – 2009-07-23 17:26:44
是的,这应该工作。额外\ n是提高效率所必需的。这样,连续的换行符被双倍和三倍(以及更多)所取代。但是单独的一个换行符是单独存在的。另外,通过使用这种方法,您不再需要循环。在这种情况下,正则表达式更好。 – 2009-07-23 17:29:20
这是一个过早的优化,以防止正则表达式浪费匹配,以'\ n'替换'\ n'这是一个NOOP。 – notnoop 2009-07-23 17:30:34
你能给一个字符串此进入一个无限循环的例子吗?此外,要调试您的程序,您可以尝试将其替换为:
while(b.IndexOf("\n\n")>=0)
{
Console.Write(b)
Console.Write(b.IndexOf("\n\n").ToString())
b = b.Replace("\n\n", "\n");
}
并查看它输出的内容。
不幸的是我的例子是一个13000字符的字符串。 我添加了一些Console.Writes,它们确认IndexOf在连续迭代中返回相同的值。 使用Visual Studio 2003,我看不到如何查看字符串并查看非打印字符。我想我可以添加更多的写入。 – Rob625 2009-07-23 17:41:29
我没有解释你无法解释的死循环(你是否确定它是无限的?你有没有检查过字符串是否改变?),但是用正则表达式可以更容易,更快速地完成:
b = System.Text.RegularExpressions.Regex.Replace(b, "\n+", "\n")
这是最好的方法,国际海事组织。 – 2009-07-23 17:29:16
我只是把这个答案放在这里来澄清一个点,以防其他人出现,并建议上面的代码将无限循环,如果b是一个空字符串。这是不正确的:
String b = String.Empty;
Console.WriteLine(b.IndexOf("\n\n"));
// output: -1
的documentation指出IndexOf
将返回0,如果传递给它的价值参数是空的,如果不是字符串本身(在这种情况下b)是空的。
我已经把问题固定在一个讨厌的字符串上,我通过阅读一个文件(下面的完整代码)。
文件s.tab包含这18个十六进制字节:FF FE 41 00 0D 0A 00 0D 0A 00 0D 0A 00 42 00
下面是我的程序输出的调试:
b.Length=8 loop n=1, i=3, b=A??
?? B
stuck at i=3, b(i)=10 2573 3328...
done n=1, i=3, b=A??
?? B
所以这与无效的unicode有关。我已经打印出字符串b的字符的十进制值,从i = 3 = IndexOf(“\ n \ n”)开始。 IndexOf似乎将10作为换行符(OK),然后是2573(即0D 0A)作为另一个(不是OK?)。然后替换不同意。
很明显,文件中的数据有问题。但我仍然认为这不应该发生。 IndexOf和Replace应该同意。
我正在实施msaeed的解决方案。非常感谢。
调试代码:
{
System.IO.StreamReader aFile = System.IO.File.OpenText(@"c:\xfer\s.tab");
string a = aFile.ReadToEnd();
aFile.Close();
int nn=0, ii;
Console.WriteLine ("a.Length={0}", a.Length);
while ((ii=a.IndexOf("\n\n")) >= 0)
{
nn++;
Console.WriteLine("loop n={0}, i={1}, a={2}"
, nn
, ii
, a);
if (ii == a.IndexOf("\n\n"))
{
Console.WriteLine ("stuck at i={0}, a(i)={1} {2} {3}..."
, ii
, (int)(a.ToCharArray()[ii])
, (int)(a.ToCharArray()[ii+1])
, (int)(a.ToCharArray()[ii+2])
);
break;
}
a = a.Replace ("\n\n", "\n");
}
Console.WriteLine("done n={0}, i={1}, a={2}", nn, ii, a);
}
你有一个例子行,其中它不会停止?一个调试器? – 2009-07-23 17:23:30
我的回答显示了一种情况下,这将迫使它来运行无限 – 2009-07-23 17:25:03
这是我如何获取引起无限循环讨厌的字符串: \t \t \t \t就是System.IO.StreamReaderå文件= System.IO.File.OpenText(@ “C:\ XFER \ s.tab”); \t \t \t \t string b = aFile.ReadToEnd(); \t \t \t \t aFile.Close(); 文件s.tab包含这些18十六进制字节: FF FE 41 00 0D 0A 00 0D 0A 00 0D 0A 00 42 00 这里是从我的节目的输出: b.length个= 8 循环n = 1, i = 3,b = A ?? ?? B 卡住在i = 3,b(i)= 10 2573 3328 ... done n = 1,i = 3,b = A ?? ?? B 所以这是无效的unicode。但我仍然认为它不应该发生。 – Rob625 2009-07-24 14:29:56