【问题标题】:Trying to add an incrementing number to all instances of a pattern in a text file尝试向文本文件中模式的所有实例添加递增数字
【发布时间】:2021-06-01 09:24:01
【问题描述】:

我是一个完整的初学者,从今天开始,但几年前我做了一点 C++,我正在尝试编写一个代码来读取文本文件并在每个递增模式的开头添加一个数字进一步阅读。

到目前为止,我已经写了:

import tkinter as tk
import re

master = tk.Tk()
from tkinter.filedialog import askopenfilename

filename = askopenfilename()
file = open(filename, "r+")
filetext = file.read()
pattern = '"name":"(.*?)"'
name = re.findall(pattern, filetext)
print (name)
namereplace = re.sub(pattern, "test", filetext)
print ("this ran")
file.close()

这会打开选择文本文件的提示,读取文本文件并找到我需要添加订单的所有字符串,但不会将它们替换为"test"

【问题讨论】:

  • 替换文本后,需要将其写入文件。这里也不需要findall
  • 更具体地说,您需要关闭文件并以"w" 模式重新打开它才能更新它。
  • @martineau 我认为使用 r+ 打开会允许读取和写入功能?
  • Adrian: 'r+' 确实允许读取和写入,但是混合了这两种操作——即在阅读文件的同时更新文件——这将非常难以实施。出于这个原因,最好在单独的步骤中重新编写整个内容(这需要跟踪大量信息)。简化事情的一种策略是将结果写入一个单独的临时文件,读取原始文件,然后删除原始文件并重命名临时文件,以便在最后替换它。

标签: python regex


【解决方案1】:

首先,要在文件中进行替换,您需要将结果实际写回文件。

为此,您有两个选择 (cmp.Replace and overwrite instead of appending):

  1. 只需在读取文件后以w 模式再次打开文件并将替换的输出写入其中即可:
import tkinter as tk
import re

master = tk.Tk()
from tkinter.filedialog import askopenfilename

filename = askopenfilename()
pattern = '"name":"(.*?)"'

with open(filename, "r") as infile:
    filetext = infile.read()
    infile.close()

with open(filename, "w") as outfile:
    outfile.write(re.sub(pattern, "test", filetext))
    outfile.close()
  1. 使用seek 移动文件的开头并使用truncate 就地替换:
import tkinter as tk
import re

master = tk.Tk()
from tkinter.filedialog import askopenfilename

filename = askopenfilename()
pattern = '"name":"(.*?)"'

with open(filename, "r+") as infile:
    filetext = infile.read()
    infile.seek(0)
    infile.write(re.sub(pattern, "test", filetext))
    infile.truncate()
    infile.close()

其次,关于你问题的主要部分,用递增的数字替换:我认为你不能通过一次调用 re.sub() 来做到这一点。

您可以做的是逐行读取文件并逐行替换计数器变量。每当您成功匹配时,您都会在之后增加您的计数器。要确定这一点,您可以例如使用re.subn(),它不仅会返回新字符串,还会返回替换的次数。

完整示例:

import tkinter as tk
import re

master = tk.Tk()
from tkinter.filedialog import askopenfilename

filename = askopenfilename()
pattern = '"name":"(.*?)"'

with open(filename, "r") as infile:
    filetext = ""
    count = 1
    line = infile.readline()
    while line:
        matchtuple = re.subn(pattern, str(count), line)
        if matchtuple[1]:
            count += 1
        filetext += matchtuple[0]
        line = infile.readline()
    infile.close()

with open(filename, "w") as outfile:
    outfile.write(filetext)
    outfile.close()

输入:

"bla":"bal"
"name":"baba"
"blah":"blah"
"name":"keke"

输出:

"bla":"bal"
1
"blah":"blah"
2

【讨论】:

  • 您的第一个建议似乎对我想要的效果很好,谢谢。现在我正在研究能够用模式替换模式的每个实例,但每次连续出现的数字都会增加。
  • 很高兴我的回答对你有用。如果是这样,您可以随时表明接受它和/或如果您愿意,可以投票。一般来说,如果您有一个不直接属于原始问题的后续问题,请考虑将其作为单独的问题发布。这让其他人更容易找到,无论他们是否有类似的问题,或者他们认为自己可以回答。
  • 话虽如此,一种做你想做的事情的方法可能是逐行读取文件(使用infile.readline()而不是infile.read()),然后用你的变量替换你的匹配项每次成功替换时递增。
  • 想一想,我猜用递增数字替换实际上是原始问题的一部分,所以我将修改我的答案以添加它。
  • 我今天刚开始做这个,完整的例子完美地保存了一个细节,我试图应用这个的文件没有任何断线,所以所有的东西都编号为 1 . 将使用 CSV 库解决此问题,非常感谢!
猜你喜欢
  • 2014-07-16
  • 2016-10-06
  • 1970-01-01
  • 2012-03-16
  • 2021-08-20
  • 2017-08-27
  • 2016-12-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多