通过Python替换文件中的更新版本字符串

通过Python替换文件中的更新版本字符串,python,regex,string,replace,Python,Regex,String,Replace,我想使用Python替换foopkg/\uuuuu init\uuuuuu.py中的版本字符串: \uuuuu version=“0.1.3” …并在setup.py中: #/usr/bin/env python 从os.path导入联接 从setuptools导入查找包,安装 version=“0.1.3” 入口点={ “控制台脚本”:[ “说foo=fooproj.foo:foo” ] } [...] 这两个文件的绝对路径和新版本号分别通过文件路径和新版本参数传递给以下函数: def u

我想使用Python替换
foopkg/\uuuuu init\uuuuuu.py
中的版本字符串:

\uuuuu version=“0.1.3”
…并在
setup.py
中:

#/usr/bin/env python
从os.path导入联接
从setuptools导入查找包,安装
version=“0.1.3”
入口点={
“控制台脚本”:[
“说foo=fooproj.foo:foo”
]
}
[...]
这两个文件的绝对路径和新版本号分别通过
文件路径
新版本
参数传递给以下函数:

def update_version_字符串(文件路径,新版本):
VERSION_REGEX=re.compile(
r“(^(\\)版本(\\)\s*=\s*\”(“P\d+\。”d+\。”d+\“$”
)
打开(文件路径“r+”)作为f:
content=f.read()
f、 搜索(0)
f、 写(
re.sub(
版本(REGEX),
lambda match:'{}{}'.format(match.group(1),新版本),
内容,,
)
)
f、 截断()
通过以下方式调用此函数:

update\u version\u字符串(“/path/to/foopkg/\uuuuuu init\uuuuuuu.py”,“0.1.4”)
…正确地将
foopgg/\uu init\uuuuuuuuuuuuuuuuuupy
中的版本号行替换为
\uuuuuuu version=“0.1.4”
,但是
更新版本字符串(“/path/to/setup.py”,“0.1.4”)
不会对
setup.py
文件产生任何更改

我认为错误在于
VERSION_REGEX
lambda match
指令的某种组合。无可否认,我对正则表达式不太精通,而且几乎肯定是以一种不太理想的方式完成的

替换这两种不同版本字符串格式并将更改写入相应文件的最佳方法是什么


优点:支持单引号样式也很好,例如
\u version\u='0.1.3'
version='0.1.3'
字符串中的版本号也将被正确替换。(^ ^ ^)

对两种不同的版本字符串格式使用以下方法(它还包括单引号/双引号):


在具有多行的文件中,匹配行首/行尾的关键是
re.M
或指令。以下函数将替换这两个
version=“0.1.3”的版本号“
\uuu version\uu='0.1.3'
字符串格式-包括单引号和双引号-在可能有多行的文件中:

def update_version_strings(file_path, new_version):
    version_regex = re.compile(r"(^_*?version_*?\s*=\s*['\"])(\d+\.\d+\.\d+)", re.M)
    with open(file_path, "r+") as f:
        content = f.read()
        f.seek(0)
        f.write(
            re.sub(
                version_regex,
                lambda match: "{}{}".format(match.group(1), new_version),
                content,
            )
        )
        f.truncate()

您这样做是为了在每个版本上发布sdist/bdist和更新版本吗?我使用Poetry来增加
pyproject.toml
中的版本,但我还想增加其他文件中的版本字符串,因为Poetry目前无法这样做。我知道有很多CLI工具可以增加版本字符串,但是对于这个用例,我希望避免添加另一个依赖项,并且更喜欢在现有代码环境中增加这些额外的版本字符串。这与预期的一样,但发现了另一个问题:只有当版本字符串是文件中的第一行时,版本字符串才会被替换。有时这是正确的(如当前在
\uuuu init\uuuuuuuuupy
中),但在诸如
setup.py
之类的文件中,在版本字符串行之前和之后还有许多其他行。为了反映这一点,我更新了原始问题中
setup.py
的示例内容。您是否知道如何修改此函数,以便适当更新包含版本字符串的任何行?
def update_version_strings(file_path, new_version):
    version_regex = re.compile(r"(^_*?version_*?\s*=\s*['\"])(\d+\.\d+\.\d+)", re.M)
    with open(file_path, "r+") as f:
        content = f.read()
        f.seek(0)
        f.write(
            re.sub(
                version_regex,
                lambda match: "{}{}".format(match.group(1), new_version),
                content,
            )
        )
        f.truncate()