简体   繁体   中英

On first occurrence of string write function writes nothing

The function:

def newstr(string, file_name, after):
    lines = []
    with open(file_name, 'r') as f:
        for line in f:
            lines.append(line)
    with open(file_name, 'w+') as f:
        flag = True
        for line in lines:
            f.write(line)
            if line.startswith(after) and flag:
                f.write(string+"\n")
                flag = False

What im running is

newstr('hello', "test.txt", "new code(")

Test.txt contents:

package example.main;

import example
public class Main {
    public static void Main() {
        new code("<RANDOM>");
        new code("<RANDOM>");
    }   

}

What I expect:

package example.main;

import example
public class Main {
    public static void Main() {
        new code("<RANDOM>");
        hello
        new code("<RANDOM>");
    }   

}

But when I run the script nothing changes.

You have lines with whitespace indentation , such as

        new code("<RANDOM>");

That line has spaces at the start; if you looked at the string representation you'd see:

>>> repr(line)
'        new code("<RANDOM>");\n'

That line does not start with 'new code(' , it starts with ' new code(' :

>>> line.startswith('new code(')
False

str.startswith() does not ignore spaces.

Either strip off the whitespace, or include whitespace in the after variable:

>>> line.strip().startswith('new code(')  # str.strip removes whitespace from start and end
True
>>> line.startswith('        new code(')
True

You could also use regular expressions to match lines, so using the pattern r'^\\s*new code\\(' .

Your mistake is that line does not start with the text you are looking for. It starts with " new code(" not "new code( . So you either need to look for " new code( or you need to strip the whitespace from the line, ie line.lstrip().startswith(... .

BTW. instead of the loop you use to read in the file you could just say lines = f.readlines() .

As there is lots of whitespace being created by the IDE you need to strip it before you can use startswith so change it to line.lstrip().startswith so that the leading whitespaces get removed next for the writing you can use an Regex to add the whitespace to your new line like this

f.write(re.search(r"\s*", line).group()+string+"\n")

Fixed code:

import re
def newstr(string, file_name, after):
    with open(file_name, 'r') as f:
        lines = f.readlines()
    with open(file_name, 'w+') as f:
        flag = True
        for line in lines:
            f.write(line)
            if line.lstrip().startswith(after) and flag:
                f.write(re.search(r"\s*", line).group()+string+"\n")
                flag = False

newstr('hello', "test.txt", "new code(")

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