使用正则表达式更改文件python中的多行

时间:2014-01-14 23:02:11

标签: python regex

我有以下文本文件,其中包含重复的数据块。我想只更改每个数据块中的值A,B,C,并将更新的数据块写入文件中。在将整个文件加载到字符串后,如何使用python结构执行此操作?

***   DATA
     1    253.31     78.20     490.0         0 0 1 0 0
   101         0         0         0         0         0         0          
     1         2         3         4         5         6
     2    123.31   -122.20     -20.0         0 0 1 0 0
   101         0         0         0         0         0         0          
     7         8         9        10        11        12
     3     53.21      10.2      90.0         0 0 1 0 0
   101         0         0         0         0         0         0          
    13        14        15        11        10        10
     .
     .
     .
    10         A         B         C         0 0 1 0 0
   110         0         0         0         0         0         0          
    20        21        22        23        24        25

4 个答案:

答案 0 :(得分:0)

我认为这段代码可能会做你想要的。

import csv

with open('my_data.csv') as data_file,\
     open('values.csv') as value_file, \
     open('my_new_data.csv', 'wb') as out_file:

    data_reader = csv.reader(data_file, delimiter=' ', skipinitialspace=True)
    value_reader = csv.reader(value_file, delimiter=',')
    writer = csv.writer(out_file, delimiter=' ')
    while True:
        try:
            row = next(data_reader)
            row[1:4] = next(value_reader)
            writer.writerows([row, next(data_reader), next(data_reader)])
        except StopIteration:
            break

如果这是输入文件:

<强> my_data.csv

 1    253.31     78.20     490.0         0 0 1 0 0
   101         0         0         0         0         0         0          
     1         2         3         4         5         6
     2    123.31   -122.20     -20.0         0 0 1 0 0
   101         0         0         0         0         0         0          
     7         8         9        10        11        12
     3     53.21      10.2      90.0         0 0 1 0 0
   101         0         0         0         0         0         0          
    13        14        15        11        10        10

<强> values.csv

1.0,2.5,3.2
4.1,5.2,6.2
7.6,8.0,9.3

<强>输出

1 1.0 2.5 3.2 0 0 1 0 0
101 0 0 0 0 0 0 
1 2 3 4 5 6
2 4.1 5.2 6.2 0 0 1 0 0
101 0 0 0 0 0 0 
7 8 9 10 11 12
3 7.6 8.0 9.3 0 0 1 0 0
101 0 0 0 0 0 0 
13 14 15 11 10 10

请注意,前导和尾随空格已消失。

答案 1 :(得分:0)

您可以使用str.replace

执行此操作
with open('data.txt', 'r') as f:
    data = f.read()

A = str(30.4)
B = str(60000)
C = str(9)

data = data.replace('A'.rjust(len(A)), A) # eg, replace '   A' with '30.4'
data = data.replace('B'.rjust(len(B)), B)
data = data.replace('C'.rjust(len(C)), C)

with open('out.txt', 'w') as f:
    f.write(data)
    f.close()

答案 2 :(得分:0)

这是你想要做的吗?

import re

data = """***   DATA
     1    253.31     78.20     490.0         0 0 1 0 0
   101         0         0         0         0         0         0          
     1         2         3         4         5         6
     .
     .
     .
     .
    10         A         B         C         0 0 1 0 0
   110         0         0         0         0         0         0          
    20        21        22        23        24        25"""
mldata = data.split('\n')

regex = re.compile(r'\b([A-Za-z])\b')
replacement = "test"

for line in mldata:
    newline = re.sub(regex,replacement,line)
    print newline

链接:ideone example

答案 3 :(得分:0)

如果我理解了你想要的东西,这里有一个保持行格式的代码:

text = """DATA gfghsg hsghghsfghsfghshsdhf
     1    253.31     78.20     490.0         0 0 1 0 0
   101        .0         0         0         0         0         0          
     1         2         3         4         5         6
     2    123.31   122.20     -20.0         0  0  1  0  0
   201         0         0         0         0         0         0          
     7         8         9        10        11        12
     6         6         .        66       666      4 8 7 4 5 7
     3     53.21      10.2      90.0e+15         0 0 1 0 0
   301         0         0         0         0         0         0          
    13        14        15        11        10        10
kjqbskjqskdkqsdbkjqsbd
   547      AFFO       457       6545   1 0 2 5 4
    10        44       138          -.017         0 0 1 0 0
   410         0         0         0         0         0         0          
    20        21        22        23        24        25
  8888      9999
   500       87E-458      12  .4
   1.2     4.E-56     
    12   45  """

import re,csv

pat = '^([ \t]*[-+]?(?:\d+\.?|\.?\d)[\deE+-]*)'\
      '([ \t]+[-+]?(?:\d+\.?|\.?\d)[\deE+-]*)'\
      '([ \t]+[-+]?(?:\d+\.?|\.?\d)[\deE+-]*)'\
      '([ \t]+[-+]?(?:\d+\.?|\.?\d)[\deE+-]*)'\
      '([ \t]*(?:[-+]?(?:\d+\.?|\.?\d)[\deE+-]*[ \t]*)*\n'\
      \
      '^[ \t]*(?:[-+]?(?:\d+\.?|\.?\d)[\deE+-]*[ \t]*)+\n'\
      \
      '^[ \t]*(?:[-+]?(?:\d+\.?|\.?\d)[\deE+-]*[ \t]*)+)$'
r = re.compile(pat,re.MULTILINE) 

def modify(text,filepath,r = r):
    with open(filepath,'rb') as vava:
        VALUES = map(tuple,
                     csv.reader(vava, delimiter='\t', skipinitialspace=True))

    dic = {}
    def ripl(m,VALUES=VALUES,dic=dic):
        lens = tuple(len(x) for x in m.group(2,3,4))
        pat = dic.setdefault(lens,'%%%ds%%%ds%%%ds' % lens)
        return m.group(1) + pat % VALUES.pop(0) + m.group(5)

    return r.sub(ripl,text)

print modify(text,'values.csv')

结果

DATA gfghsg hsghghsfghsfghshsdhf
     1    100000      0.01    101.01         0 0 1 0 0
   101        .0         0         0         0         0         0          
     1         2         3         4         5         6
     2         2     0.02     20022         0  0  1  0  0
   201         0         0         0         0         0         0          
     7         8         9        10        11        12
     6         6         .        66       666      4 8 7 4 5 7
     3      3303     0.033       3.03333         0 0 1 0 0
   301         0         0         0         0         0         0          
    13        14        15        11        10        10
kjqbskjqskdkqsdbkjqsbd
   547      AFFO       457       6545   1 0 2 5 4
    10       4.4      0.44            4.4         0 0 1 0 0
   410         0         0         0         0         0         0          
    20        21        22        23        24        25
  8888      9999
   500          5555 0.5555555e+55
   1.2     4.E-56     
    12   45

部分

lens = tuple(len(x) for x in m.group(2,3,4))
pat = dic.setdefault(lens,'%%%ds%%%ds%%%ds' % lens)

是一种复杂性,考虑到格式对于所有修改的行不一定总是相同的可能性。因此,它检查包含4个第一个值的行的4个第一部分的长度:如果这些值已知,则从字典dic获取相应的模式,如果不是,则创建并放置新模式在字典里。