我正在處理一些相當低效的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