文章目录
- 背景
- 1、定义正则表达式
- 2、替换变量占位符
- 3、实现功能
背景
使用python
编写小工具,有一个配置文件,希望实现类似shell
命令的,定义变量并且使用${}
或者$
来引用。如果有好的建议欢迎讨论。
配置文件示例内容如下:
D:\project\test\properties.txt
ip=192.168.1.66
user=xiaoshuai
password=123456
login_url=https://${ip}/index.php/user=$user?password=$password?name=${user}
总体思路如下:
- 读取文件,存储出现的变量
- 将存在占位符的变量,使用已读取的变量替换。如果找不到则不替换。
1、定义正则表达式
首先先需要将替换的代码写好,这里直接使用正则表达式替换占位符,然后使用变量进行替换。
# 定义正则表达式
pattern = re.compile(r'\$\{(\w+)}|\$(\w+)')
这个表达式包含可以匹配用${}
或者$
形式的占位符,且有两个捕获组,用以获取占位符中实际的变量。
2、替换变量占位符
需要替换的字符串如下:
string = r"https://${ip}/index.php/user=$user?password=$password?name=${user}"
这里可以使用正则表达式sub()
函数进行替换
# 使用正则表达式进行替换
result = pattern.sub(replace, string)
replace
可以是具体的替换字符串,也可以是自定义函数。因为这里需要根据占位符的实际内容来获取不同的变量值,所以需要使用自定义的函数:
# 替换占位符的回调函数
def replace(match):
var_name = match.group(1) if match.group(1) else match.group(2)
return str(param_dict.get(var_name, match.group()))
replace
函数首先检查第一个捕获组,如果存在则使用它,否则使用第二个捕获组。这样就可以处理 ${variable}
和 $variable
形式的占位符了。
当然也可以使用lambda
匿名函数一行处理,那么sub
的写法则为:
result = pattern.sub(lambda x: str(param_dict.get(x.group(1) if x.group(1) else x.group(2), x.group())), string)
3、实现功能
读取文件、存储变量、替换占位符和变量
import re
path = r'D:\project\test\properties.txt'
var_dict = dict()
# 定义正则表达式
pattern = re.compile(r'\$\{(\w+)}|\$(\w+)')
with open(path, 'r') as file:
for line in file:
line = line.replace('\n', '').strip()
if not line:
continue
# 获取配置项
key = line.split('=')[0].strip()
value = line.replace(key, '', 1).replace('=', '', 1).strip()
# 将value中的通配符替换为实际的值
value = pattern.sub(lambda x: str(var_dict.get(x.group(1) if x.group(1) else x.group(2), x.group())), value)
var_dict[key] = value
for k, v in var_dict.items():
print(f"{k}\t{v}")
结果如下: