2009-09-14 34 views
2

我有一個類似CSV的文本文件,大約有1000行。文件中的每條記錄之間都是一連串的破折號。記錄通常以\ n結尾,但有時在記錄結束之前會有一個額外的\ n。簡化示例:換行符後的負向向前?

"1x", "1y", "Hi there" 
------------------------------- 
"2x", "2y", "Hello - I'm lost" 
------------------------------- 
"3x", "3y", "How ya 
doing?" 
------------------------------- 

我想用空格替換多餘的\ n,即連接破折號之間的連線。我想我能做到這一點(Python 2.5中):

text = open("thefile.txt", "r").read()  
better_text = re.sub(r'\n(?!\-)', ' ', text) 

,但似乎每次替換\ n,不只是不跟一個破折號的人。我究竟做錯了什麼?

我在問這個問題,試圖提高自己的正則表達式技能,並理解我犯的錯誤。最終目標是生成一種文本文件,其格式可由特定的VBA for Word宏使用,從而生成一個樣式化的Word文檔,然後由Word友好的CMS進行消解。

+0

如果這是Perl,我會說'$ /'設置爲''------------------------------- ' – 2009-09-14 19:11:08

回答

5

您需要排除分隔線末尾的換行符。試試這個:

\n(?<!-\n)(?!-) 

這個正則表達式使用負look-behind assertion排除\n多數民衆贊成由- preceeded。

+0

謝謝,我現在看到了。在嘗試解決方案之前,我沒有徹底地定義問題,然後通過假設在實際替換一半時替換所有的\ n來進一步混淆事物。 – fwkb 2009-09-14 19:33:25

1
re.sub(r'(?<!-)\n(?!-)', ' ', text) 

(連字符不需要字符類以外逃逸。)

+0

...以及字符範圍聲明之外和claracter類的開始或結尾處。 '[a-z-0-9]','[-a-z]'和'[a-z-]'都是有效的字符類聲明。 – Gumbo 2009-09-14 19:41:48

7

這是使用生成函數跳過的線條和產生的東西,csv模塊的好地方可以閱讀。

def readCleanLines(someFile): 
    for line in someFile: 
     if line.strip() == len(line.strip())*'-': 
      continue 
     yield line 

reader= csv.reader(readCleanLines(someFile)) 
for row in reader: 
    print row 

這應該無縫默默地處理引號內的換行符。


如果你想要做其他事情與此文件,例如,保存與線除去副本,你可以做到這一點。

​​

這將刪除行的副本。這並不值得,因爲讀取和跳過這些行非常快,並且不需要額外的存儲空間。

+1

真棒的想法,用發生器去除線條! – orip 2009-09-14 19:33:16

+0

順便說一句 - 你不需要len(line.strip())而不是len(line)? – orip 2009-09-14 19:34:13

+0

@orip:這將是一個錯誤,謝謝。 – 2009-09-14 20:05:00

0

RegEx並不總是最適合這項工作的工具。如何通過諸如「Split」或「Tokenize」之類的東西來運行它? (我相信python有一個等價的)然後你有你的記錄,並可以假設換行符只是延續。