我想使用Python替换foopkg/__init__.py
中的版本字符串:
__version__ = "0.1.3"
...以及setup.py
中的
#!/usr/bin/env python
from os.path import join
from setuptools import find_packages, setup
version = "0.1.3"
entry_points = {
"console_scripts": [
"say-foo = fooproj.foo:foo"
]
}
[...]
这两个文件的绝对路径以及新版本号分别通过file_path
和new_version
参数传递给以下函数:
def update_version_strings(file_path, new_version):
VERSION_REGEX = re.compile(
r"(^(__)?version(__)?\s*=\s*\")(?P<version>\d+\.\d+\.\d+)\"$"
)
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()
通过以下方式调用此功能:
update_version_strings("/path/to/foopkg/__init__.py", "0.1.4")
…正确地将foopkg/__init__.py
中的版本号行替换为__version__ = "0.1.4"
,但是update_version_strings("/path/to/setup.py", "0.1.4")
对setup.py
文件没有任何改变。
我认为错误在于VERSION_REGEX
和lambda match
指令的某种组合。我当然不熟悉正则表达式,并且几乎可以肯定以不太理想的方式做到了这一点。
替换这两种不同版本的字符串格式并将更改写入相应文件的最佳方法是什么?
奖金点:最好也支持单引号样式,这样__version__ = '0.1.3'
和version = '0.1.3'
字符串中的版本号也将被正确替换。 (^ _ ^)
答案 0 :(得分:1)
使用以下方法处理两种不同版本的字符串格式(还涵盖单引号/双引号):
def update_version_strings(file_path, new_version):
version_regex = re.compile(r"(^_*?version_*?\s*=\s*['\"])(\d+\.\d+\.\d+)")
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()
答案 1 :(得分:0)
在多行文件中,匹配行首/结尾的关键是['A', 'Z', 'B', 'Y', 'C', 'X', 'D', 'W', 'E', 'V', 'F', 'U', 'G', 'T', 'H', 'S', 'I', 'R', 'J', 'Q', 'K', 'P', 'L', 'O', 'M', 'N', 'N', 'M', 'O', 'L', 'P', 'K', 'Q', 'J', 'R', 'I', 'S', 'H', 'T', 'G', 'U', 'F', 'V', 'E', 'W', 'D', 'X', 'C', 'Y', 'B', 'Z', 'A']
或re.MULTILINE
伪指令。以下函数在可能有多行的文件中替换re.M
和version = "0.1.3"
字符串格式的版本号(包括单引号和双引号):
__version__ = '0.1.3'