简体   繁体   中英

Python - Write to specific part of file, not by line - Regex

What I would like to do is write in a value into a specific part of a file. This part can be anywhere in the file, but will appear only once, therefore I don't believe adding a line will solve it.

What I have is essentially a text file with:

TitleThing (
Some info = 22 

(More info = 22.2)
Tags = [] 
)

What I would like to do is add a string to the file right inside of the [] after Tags =.

Would looks like:

TitleThing (
Some info = 22 
Otherthing -- "56.foo"
(More info = 22.2)

Tags = ["newtag"] 
)

The other issue is that there may be existing tags:

TitleThing (
Some info = 22 

(More info = 22.2)
Tags = ["oldtag, othertag"] 
)

In this situation I would like to add my "newtag" to the exiting list so that it appears first.

I have start with:

tagRegex = re.compile(r'Tags = [(.*)]')

But I'm not sure how to proceed.

Would love some help!

Thanks.

A dirty idea: you could read the line with Tags = ... , evaluate it, edit the list, then rewrite it:

exec('Tags = ["newtag"]')
Tags.append("othertag")
f.write('Tags = {}'.format(Tags))

where f is a new file where you write the edited version (or use a temp file as in the other answer).

(Of course it is always dangerous to execute an arbitrary string, but that works if it is a one-time script.)

You need to write to a temporary file then overwrite the original.

from tempfile import NamedTemporaryFile
from shutil import move


def add_new(new):
    with open("check.txt") as f, NamedTemporaryFile("w",delete=False) as tmp:
        for line in f:
            if line.startswith("Tags ="):
                repl = ", {}]".format(new) if "[]" not in line else "{}]".format(new)
                tmp.write(line.replace("]", repl))
                tmp.writelines(f)
                break
            tmp.write(line)
    move(tmp.name, "check.txt")

Then just pass in the new value:

In [3]: cat check.txt
TitleThing (
Some info = 22 

(More info = 22.2)
Tags = []
)
In [4]: add_new("newvalue")

In [5]: cat check.txt
TitleThing (
Some info = 22 

(More info = 22.2)
Tags = [newvalue]
)
In [6]: add_new("newvalue2")

In [7]: cat check.txt
TitleThing (
Some info = 22 

(More info = 22.2)
Tags = [newvalue, newvalue2]
)

If you wanted the new value at the start, you need to just change the logic slightly:

   repl = "[{}, ".format(new) if "[]" not in line else "[{}".format(new)
   tmp.write(line.replace("[", repl))

Based on your comment change the if to:

if  '"Tags": [' in line:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM