【问题标题】:Replace line in file using re使用 re 替换文件中的行
【发布时间】:2021-06-29 19:04:16
【问题描述】:

为什么我的代码不能正常工作? 我正在尝试使用 re 模块替换文件中的一行:

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)

我已经通过使用fileimport 库来做到这一点,但这不是方法。为什么模式打印效果好时不能正常运行,re.sub() 应该在文件中的这个位置替换它?

【问题讨论】:

  • re.sub 创建一个新字符串,它不会以任何方式修改文件。
  • 您到底期望会发生什么,但会发生什么?

标签: python regex replace python-re


【解决方案1】:

你的第一个问题是做完之后...

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

...您现在位于文件末尾,所以当您这样做时...

for line in file:

...没有更多的行要读取。正如@bb1 所评论的那样,re.sub 返回一个新字符串并且不会更新任何内容。

假设您想用更新的文本替换文件,如果您将整个文件作为一个字符串读取(您现在位于文件末尾),进行文本替换,重新定位回来会容易得多到文件的开头,重新编写新字符串,然后截断文件中可能出现的任何剩余字符:

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

但我质疑你的 pattern 正则表达式。如果输入有以下任何一项怎么办?

post_max_size = 1234
post_max_size=1234k
post_max_size = 1234G

您只匹配一个单个数字。也许你的模式应该是:

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

注意:在原地更新文件时总是存在一些危险。如果由于某种原因计算机在写入操作过程中崩溃,您将丢失原始内容。因此,您可能需要确保在继续之前进行备份。

【讨论】:

    【解决方案2】:

    尝试在正则表达式中使用分组括号:

    pattern = re.compile(r'(post_max_size\s=\s[0-9])')
    pattern.sub("post_max_size = 1G", file.read())
    

    【讨论】:

    • 创建捕获组 1,您甚至没有在替换字符串中引用它,不会产生任何影响。 OP 还有其他问题,您只是在创建一个更昂贵的正则表达式。
    【解决方案3】:

    更好的正则表达式将是这个问题的下一个很好的解决方案。非常感谢,现在很简单了。 我将使用此技巧修改脚本,因为重要的是不要丢失 prod 服务器上的数据。

    【讨论】:

      猜你喜欢
      • 2019-04-10
      • 1970-01-01
      • 2017-09-23
      • 1970-01-01
      • 2011-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-02
      相关资源
      最近更新 更多