【问题标题】:How to .replace from a line to another in a .txt, if the line to be replaced is above the line where i'll get the value for replacement?如果要替换的行高于我将获得替换值的行,如何在 .txt 中将一行替换为另一行?
【发布时间】:2015-10-07 06:32:00
【问题描述】:

首先,抱歉我的标题太长了..我无法用简单的方式解释它..随意编辑它!

我需要一些逻辑帮助来解决我的问题...

我有一个具有以下特征的 .txt 文件:

  1. 每一行对应一个特定的操作...
  2. 行的每个字段由“|”分隔分隔符
  3. 我的 .txt 有 120k+ 行,但我的发票只有 60k~ 行
  4. 我必须复制以 C195 开头的行中的值,并将它们替换到 C100 行中紧邻 C195 行上方的特定字段中。

示例:

我的 .txt 中的发票部分如下:

  • |C100|1|1238761|128,82|1002,21|0,00|0,00|0,00|0,00 |
  • |C170|1|414859|Mini Leitoa|Kg|21,80|KG|
  • |C190|363,53|0,00|0,00|0,00|0,00|0,00|0,00|
  • |C195|C195|1|Base de Cálculo ST:193,56 - Valor da ST:10,10|
  • |C195|C195|2|Valor do IPI: 7,10|

它应该是什么:

  • |C100|1|1238761|128,82|1002,21|0,00|193,56|10,10|7,10 |
  • |C170|1|414859|Mini Leitoa|Kg|21,80|KG|
  • |C190|363,53|0,00|0,00|0,00|0,00|0,00|0,00|
  • |C195|1|Base de Cálculo ST:193,56 - Valor da ST:10,10|
  • |C195|2|Valor do IPI: 7,10|

到目前为止我做了什么:

  1. 创建了一个程序来读取我的 txt 行并将它们存储在 input_lines = []
  2. 获取input_lines中以C100开头的行的index(),并将它们存储在pos_c100 = []
  3. 由于我的 C195 字段可以包含 Tax1 (ICMS) 或 Tax2 (IPI) 的值,我使用 re.search(param,string) 来查找该行是否包含“ICMS”或“IPI”。
  4. 如果该行包含“ICMS”,它将包含两个值:第一个是icms_basis,另一个是icms_value
    • |C195|1|Base de Cálculo ST: 193,56 - Valor da ST: 10,10|
  5. 如果该行包含“IPI”,它将包含 1 个值:只有 ipi_value
    • |C195|1|Valor do IPI: 10,10|
  6. 我已使用 re.findall() 从字符串中提取值,并将它们存储在带有行位置的“特定税收字典”中

由于每个值都有一个特定的位置要替换,而且我已经知道这些位置,所以我创建了 2 个字典来保存 C195 行的索引及其值,一个用于 IPI,另一个用于 ICMS。

我的数据布局:

pos_c100 = [line_c100]
dic_icms = {line_c195 : [icms_basis, icms_value]}
dic_ipi = {line_c195 : ipi_value}

我现在运行脚本后得到的结果,例如:

input_lines = ["|C100|1..", "|C170|1..", "|C195|1|IPI..", "C195|1|ICMS.."] #the output of `file.readlines()`
pos_c100 = [2, 4, 8, 10] #the positions of the lines that start with C100
dic_icms = {6 : ["200,15", "15,80"]} #{key, [icms_basis, icms_value]}
dic_ipi = {7 : "7,15"} # {key, icms_}
#key is the position of the lines that startswith c195 in input_lines 

以上面的dic_icms为例:

如何从dic_icms 获得"200,15""15,80", 位于lines_input 的第 6 位的行,以及 将其替换在第 4 个位置的行的特定位置 lines_input 在我的字典中使用循环?

我需要一种方法来检查这条线是否是上面最接近的,如果是, 替换引用字典值的值...

也许有一个

for key in dic_ipi:
    for item in pos_c100:
        dists = []
        dist = key - item
        dists.append(dist)

linha = (linha[0:posInicialBcICMS] + linha[posInicialBcICMS:posFinalBcICMS].replace("0,00", ICMS_BASIS) + linha[posInicialVlrICMS:posFinalVlrICMS].replace("0,00", ICMS_VALUE) + linha[posInicialVlrIPI:posFinalVlrIPI].replace("0,00", IPI_VALUE) + linha[posFinalVlrIPI + 1 : len(linha)])

【问题讨论】:

    标签: python python-2.7 dictionary text replace


    【解决方案1】:

    让我们从读取文件开始:

    file = open("blabla.txt", "r").
    data = file.read()
    file.close()
    

    输出数据包含整个文本。通过使用split:

    data = data.split("\n") #splitting by \n
    

    你会得到一个看起来像这样的大数组:['line1', 'line2', 'line3'...]。我们需要创建新表:

    new_table = []
    

    现在是进行繁重操作的时候了。由于您的线路看起来像|C170|1|414859|Mini Leitoa|Kg|21,80|KG|,您可以再次使用split()

    for line in data:
        new_table.append(line.split("|") # split returns new table splitted by "|". Append adds this table to new_table in the last position.
    

    new_table 看起来像这样:[[line1_element1, line1_element2, line1_element2], [line2_element1, line2_element2, line2_element3],...]。现在您应该可以使用len() 函数来获取特定表的长度。例如:

    for i in xrange(0, len(new_table)): # iterating through lines, but 'i' is integer type from 0 to len(new_table)
        for j in xrange(len(new_table[i])): # iterating through each element in 'i' line (i is index of new_table)
            print new_table[i][j] # this will print j element of i line in new_table
    

    如果您可以通过索引访问每一行中的每个元素,您可以使用if 语句轻松比较所有内容。例如:

    if new_data[i][j] == "C165":
        do_something()
    

    希望对您有所帮助。 - 编辑 - 你问的是最近的线路。它将是 ij 元素 +- 1。

    【讨论】:

      猜你喜欢
      • 2017-08-14
      • 2018-10-23
      • 1970-01-01
      • 1970-01-01
      • 2018-09-04
      • 2022-01-18
      • 1970-01-01
      • 2017-10-11
      • 1970-01-01
      相关资源
      最近更新 更多