我正在编写一个 fabfile,但在替换时遇到问题。我已经使用 regex101 检查过,它表明我的正则表达式有效(无论有没有“扩展”开关)。但是,当我运行 fabfile 时,没有替换。正则表达式是:
ALLOWED_HOSTS\ ?=\ ?\[([^]]+)\]
它应该匹配 Django settings.py 文件中的任何 ALLOWED_HOSTS,从空定义到多行定义。要匹配的最小文本是
ALLOWED_HOSTS = []
要匹配的多行文本可能如下所示:
ALLOWED_HOSTS = [
'django-stage.somedomain.com',
'django-deployment.somedomain.com',
'localhost',
]
换句话说,正则表达式应匹配包含“ALLOWED_HOSTS”的字符串,后跟 0 或 1 个空格,等号“=”,后跟 0 或 1 个空格,后跟前括号“[”,后跟任意文本(包括换行符),后跟后括号“]”。但是,当运行 fabfile 时,上面的行不会更改。 fabfile 中的完整函数:
def _update_settings(source_folder, site_name):
settings_path = source_folder + '/appname/settings.py'
sed(settings_path, "DEBUG = True", "DEBUG = False")
sed(settings_path,
'ALLOWED_HOSTS\ ?=\ ?\[([^]]+)\]',
f'ALLOWED_HOSTS = ["{site_name}"]'
)
运行时,输出为:
[django-stage.somedomain.com] 运行: sed -i.bak -r -e 's/ALLOWED_HOSTS\?=\?[([^]]+)]/ALLOWED_HOSTS = ["django-stage. somedomain.com"]/g' "$(echo/srv/django-stage.somedomain.com/source/appname/settings.py)"
非常感谢任何帮助。
最佳答案
我想我会冒昧地回答我自己的问题,因为我现在已经得到了上面的脚本。该函数需要如下所示:
def _update_settings(source_folder, site_name):
settings_path = source_folder + '/appname/settings.py'
sed(settings_path, "DEBUG = True", "DEBUG = False")
run(
"sed -e '1h;2,$H;$!d;g' -i.bak -re 's/"
+ "ALLOWED_HOSTS\ ?=\ ?\[([^]]*)\]/"
+ "ALLOWED_HOSTS = \[\"" + site_name + "\"\]/' "
+ settings_path
)
@antak 在 "How can I use sed to replace a multi-line string?" 中明确解释了 -e '1h;2,$H;$!d;g' 的含义 .
开关:
-r:-r 开关用于扩展正则表达式(也可以是 -E 或 --regexp-extended)。
-e:分隔命令。
-i:就地替换。 i.bak表示将原文件备份到filename.bak。
至于正则表达式模式:
ALLOWED_HOSTS\ ?=\ ?\[([^]]*)\]
- ALLOWED_HOSTS 按字面意思匹配字符 ALLOWED_HOSTS(区分大小写)
- \?从字面上匹配空格字符
- ?量词 - 匹配零到一次,尽可能多的次数
- = 按字面意思匹配等号
- \?从字面上匹配空格字符
- ?量词 - 零次和一次之间的匹配
- \[ 按字面意思匹配左方括号
- 第一捕获组 ([^]]*)
- 匹配列表中不存在的单个字符[^]]*,即不是右方括号的字符
- * 量词 - 匹配次数为零到无限次,尽可能多次 表达式 ^] 中的
] 与右方括号字符字面匹配
\] 按字面意思匹配右方括号字符
运行 fabfile 的输出(site_name = somedomain):
[somedomain] run: sed -e '1h;2,$H;$!d;g' -i.bak -re 's/ALLOWED_HOSTS\ ?=\ ?\[([^]]*)\]/ALLOWED_HOSTS = \["somedomain"\]/' /path_to_settings_file/settings.py
关于python - Fabric 中的正则表达式和 sed 出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54631171/