【问题标题】:Create Output file with multiple lines (Python)创建多行输出文件(Python)
【发布时间】:2011-03-01 13:10:18
【问题描述】:

我有一个文件,其中包含我想要提取的特定数据。

文件如下所示:

DS User ID 1  
random garbage  
random garbage  
DS  N user name 1   
random garbage  
DS User ID 2   
random garbage  
random garbage  
DS  N user name 2

到目前为止我有:

import sys  
import re  
f = open(sys.argv[1])

strToSearch = ""

for line in f:
        strToSearch += line

patFinder1 = re.compile('DS\s+\d{4}|DS\s{2}\w\s{2}\w.*|DS\s{2}N', re.MULTILINE)

for i in findPat1:  
    print(i)

我的屏幕输出如下所示:

DS user ID 1  
DS  N user name 1  
DS user ID 2  
DS  N user name 2   

如果我使用以下方式写入文件:

outfile = "test.dat"   
FILE = open(outfile,"a")  
FILE.writelines(line)  
FILE.close()  

所有内容都被推送到一行:

DS user ID 1DS  N user name 1DS user ID 2DS  N user name 2 

我可以接受输出的第一个场景。理想情况下,虽然我想从输出文件中删除“DS”和“DS N”并用逗号分隔。

User ID 1,user name 1  
User ID 2, username 2

关于如何完成此任务的任何想法?

【问题讨论】:

  • 嗨,欢迎来到 StackOverflow。请花一点时间熟悉一下编辑器,尤其是可用于格式化代码的代码按钮 {}
  • 这显然不是你真正的程序。一方面,您永远不会使用正则表达式。它也与您提供的样本不匹配,至少与大多数样本不匹配。你永远不会定义findPat1
  • 请清楚地描述您的输入数据是什么样的以及您使用什么标准来匹配。从您的样本看来,寻找以DS 开头的行就足够了——如果不是,请说明规则。您似乎正在尝试匹配相应的用户 ID/用户名条目。如果我们知道您在做什么,我们肯定可以向您展示更好的方法。

标签: python text


【解决方案1】:

如果不了解实际的输入数据格式、允许的灵活性以及解析后的数据将如何使用,就很难提供稳健的解决方案。

仅从上面给出的示例输入/输出,我们可以快速编写一个有效的示例代码:

out = open("test.dat", "a") # output file

for line in open("input.dat"):
    if line[:3] != "DS ": continue # skip "random garbage"

    keys = line.split()[1:] # split, remove "DS"
    if keys[0] != "N": # found ID, print with comma
        out.write(" ".join(keys) + ",")
    else: # found name, print and end line
        out.write(" ".join(keys[1:]) + "\n")

输出文件将是:

User ID 1,user name 1
User ID 2,user name 2

如果格式规范已知,当然可以使用正则表达式使这段代码更加健壮。例如:

import re
pat_id = re.compile(r"DS\s+(User ID\s+\d+)")
pat_name = re.compile(r"DS\s+N\s+(.+\s+\d+)")
out = open("test.dat", "a")

for line in open("input.dat"):
    match = pat_id.match(line)
    if match: # found ID, print with comma
        out.write(match.group(1) + ",")
        continue
    match = pat_name.match(line)
    if match: # found name, print and end line
        out.write(match.group(1) + "\n")

上面的两个例子都假设“用户 ID X”总是出现在“N 用户名 X”之前,因此分别有“,”和“\n”的尾随字符。

如果顺序不明确,可以使用数字 ID 作为键将值存储在字典中,然后在解析所有输入后打印出 ID/名称对。

如果您提供更多信息,也许我们可以提供更多帮助。

【讨论】:

  • 效果很好,正是我需要的。谢谢。试图摆脱DS和DS N,它会是完美的。
【解决方案2】:

print 在参数后添加换行符,但 writelines 没有。所以你必须这样写:

file = open(outfile, "a")
file.writelines((i + '\n' for i in findPat1))
file.close()

writelines 语句也可以写成:

for i in findPat1:
    file.write(i + '\n')

【讨论】:

    【解决方案3】:
    FILE.writelines(line)
    

    不添加行分隔符。

    只要做:

    FILE.write(line + "\n")
    

    或者:

    FILE.write("\n".join(lines))
    

    【讨论】:

      【解决方案4】:
      import re
      
      ch ='''\
      DS User ID 1
      random garbage
      random garbage
      DS  N user name 1
      random garbage
      DS User ID 2
      random garbage
      random garbage
      DS  N user name 2'''
      
      RE = '^DS (User ID (\d+)).+?^DS  N( user name \\2)'
      
      with open('outputfile.txt','w') as f:
          for match in re.finditer(RE,ch,re.MULTILINE|re.DOTALL):
              f.write(','.join(match.groups())+'\n')
      

      编辑:

      替换

      RE = '^DS (User ID \d+).+?^DS  N( user name \d+)'
      

      RE = '^DS (User ID (\d+)).+?^DS  N( user name \\2)'
      

      【讨论】:

        猜你喜欢
        • 2020-06-20
        • 1970-01-01
        • 2011-07-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多