Search code examples
pythonregexreplacepython-re

Replace line in file using re


Why is my code not working properly? I'm trying to replace one line in file using the re module:

import re

file = open("php.ini", "r+")

pattern = r'post_max_size = [0-9]'
result = re.search(pattern, file.read())

for line in file:        
    re.sub(pattern, "post_max_size = 1G", file.read())

file.close()
print(result)

I have done this by using the fileimport library, but this is not the way. Why can't it run properly while pattern is printing good result and re.sub() should replace it in this place in file?


Solution

  • Your first problem is that after doing ...

    result = re.search(pattern, file.read())
    

    ... you are now at the end of file and so when you do ...

    for line in file:
    

    ... there are no more lines to be read. And as was commented on by @bb1, re.sub return a new string and does not update anything in place.

    Assuming you want to replace the file with the updated text, it is far easier if you read the entire file in as one string (you are now positioned at the end of file), make the textual substitutions, re-position back to the start of the file, re-write the new string and then truncate what might be any leftover characters following in the file:

    import re
    
    pattern = r'post_max_size = [0-9]'
    with open("php.ini", "r+") as file:
        text = file.read()
        text = re.sub(pattern, "post_max_size = 1G", text)
        file.seek(0, 0) # seek to beginning
        file.write(text)
        file.truncate() # get rid of any trailing characters
    

    But I question your pattern regex. What if the input had any of the following?

    post_max_size = 1234
    post_max_size=1234k
    post_max_size = 1234G
    

    You are only matching a single digit. Perhaps your pattern should be:

    pattern = r'post_max_size\s*=\s*[0-9]+[kKgG]?'
    

    Note: There is always a bit of danger when you are updating a file in place. Should for some reason the computer crash in the middle of the write operation, you will have lost the original contents. You might want to therefore be sure to have a backup before proceeding.