2009-09-14 85 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有一个等价的)然后你有你的记录,并可以假设换行符只是延续。