Python:删除复杂的多行字符串

时间:2017-07-04 07:29:20

标签: python

我有一个包含许多不同文本的文件,如下所示:

Family number: 1
    Names: Bob, Linda, Dave
    Message: Some message here.

...

......有数百个条目。

其中一些看起来像这样:

Family number: 1
    Names: Bob, Linda,\
    \ Dave
    Message: Some message here.

这是由于某些其他信息收集模块完成的一些上游格式问题,我不能影响(或者说不应该惹恼)。

我希望看起来像后者的条目看起来像前者。

从我可以收集的内容来看,我想删除的模式出现在多行上。我最初的策略是搜索模式

,\\n    \

并将其替换为''因为我不确定文件中是否有其他位置可能没有第一个逗号的模式。

通常我会做这样的事情:

for line in fileinput.input(['file.txt'], inplace=True):
    print(line.replace(',\\n    \',','), end='')

...但这仅适用于单行。我也尝试过:

with open('file.txt', 'r') as in_file:
    with open('file.txt.tmp', 'w') as out_file:
       content = in_file.read()
       pattern = re.compile(r',\\n    \')
       to_be_printed = re.sub(pattern, ",", to_be_printed)
       out.write(to_be_printed)

这不起作用,并且似乎没有内存效率,因为它涉及将整个文件读入内存。

有没有办法可以整齐地完成这项工作?

2 个答案:

答案 0 :(得分:0)

import re
text =  open(path).read()

# Replace multiline delimited by \
pattern = r'\\\n+[ \t]*\\'
new_text = re.sub(pattern, ",", text)

# Replace 2+ commas in a row (if that's an issue)
pattern = r',{2,}'
new_text = re.sub(pattern, ",", new_text)

提供所有匹配的工作是否与您的示例相同。对于数百个条目,内存效率不是您应该担心的。

答案 1 :(得分:0)

读取整个文件是可以的,因为你试图捕捉多行出现,因此如果你问我,re是可以选择的。

我认为你需要某种this模式。正如@jadsq在评论部分中提到的那样 - 你的错误是\字符的错误转义!

让我们看看我们可以用它做什么:

import re

#   input block
input_data = r'''
Family number: 1
    Names: Bob, Linda,\
    \ Dave
    Message: Some message here.
'''
print('*** Input data: ***\n%s' % input_data)

#   re-place block
pattern = re.compile(r',\\\n\s+\\', re.M | re.I)
output_data = re.sub(pattern, ",", input_data)

#   output block
print('*** Output data: ***\n%s' % output_data)

<强>输出:

*** Input data: ***

Family number: 1
    Names: Bob, Linda,\
    \ Dave
    Message: Some message here.

*** Output data: ***

Family number: 1
    Names: Bob, Linda, Dave
    Message: Some message here.

<强>解释

,                matches the character , literally.
\\               matches the character \ literally (another \ for eascape purpose).
\n               matches a line-feed (newline) character (to ensure that there is a newline).
\s+              matches any whitespace character (one or more).
\\               matches the character \ literally (another \ for eascape purpose).

如果你遇到困难 - 先自己在 regex101 上玩,如果有问题 - 用更多数据更新你的问题并添加标签以产生一些正则表达大师。

部分链接:

希望它有所帮助!