你好python和正则表达式专家!
我有一个包含很多yaml文件的文件树,我需要在文件中的几个位置更改路径字符串。
yaml文件可能如下所示:
- !import ../../../app/app.yml
- !import ../../fw/fw/app.yml
- !import ../../id/id/app.yml
includes: [ ../, ../../../app/include/, ../../fw/include, ]
includes:
- ../
- ../../../app/include/
- ../../fw/include
需要更改为:
- !import ../../../Sys/app/app.yml
- !import ../../Sys/fw/fw/app.yml
- !import ../../id/id/app.yml
includes: [ ../, ../../../Sys/app/include/, ../../Sys/fw/include, ]
includes:
- ../
- ../../../Sys/app/include/
- ../../Sys/fw/include
...因此,每条路径必须以/ Sys为前缀,因为指向的文件的位置已更改。请注意,不得更改某些路径:' - !import ../../id/id/app.yml'不得更改(+可能还有其他路径)
上面的示例中有两个包含标记,因为它与在要更改的文件中写入的方式不同。
所以我需要一个适用于上述组合的正则表达式。我已经尝试了很多次迭代,但是我还想要涵盖两个包含标签。
注意:我宁愿使用纯文本文件解析而不是使用pyaml,以免破坏文件格式,因为其中一些文件包含大量注释。
欢迎任何建议 - 谢谢
答案 0 :(得分:0)
试试这个:
input = re.sub("((?:\.\./)+)(?=[a-zA-Z0-9])", '\\1Sys/', input)
捕获连续的../
,如果后面跟着一个字母数字,则在组\\1
中捕获它
答案 1 :(得分:0)
我会用这样的东西:
output = re.sub(r"\.\./(?=\w)(?!id)", "../Sys/", input)
请注意,由于有关不应更改内容的信息有限,因此很难找到一个不能替换某些文件路径的信息。正则表达式处理模式,因此没有适当的规则,您必然会发现缺点。
答案 2 :(得分:0)
import re
pat = re.compile(r"""
((\.\./){2,}) # at least two levels up
(?!id/) # no replace of id/ paths
(.*?)
""", flags=re.VERBOSE)
print pat.sub(r"\1Sys/\3", yaml)
输出:
- !import ../../../Sys/app/app.yml
- !import ../../Sys/fw/fw/app.yml
- !import ../../id/id/app.yml
includes: [ ../, ../../../Sys/app/include/, ../../Sys/fw/include, ]
includes:
- ../
- ../../../Sys/app/include/
- ../../Sys/fw/include