更改yaml文件中的路径

时间:2014-03-27 19:07:19

标签: python regex

你好python和正则表达式专家!

我有一个包含很多yaml文件的文件树,我需要在文件中的几个位置更改路径字符串。

yaml文件可能如下所示:

BEFORE

- !import ../../../app/app.yml
- !import ../../fw/fw/app.yml
- !import ../../id/id/app.yml

includes:    [ ../, ../../../app/include/, ../../fw/include, ]

includes:
    - ../
    - ../../../app/include/
    - ../../fw/include

需要更改为:

WANTED

- !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,以免破坏文件格式,因为其中一些文件包含大量注释。

欢迎任何建议 - 谢谢

3 个答案:

答案 0 :(得分:0)

试试这个:

input = re.sub("((?:\.\./)+)(?=[a-zA-Z0-9])", '\\1Sys/', input)

捕获连续的../,如果后面跟着一个字母数字,则在组\\1中捕获它

答案 1 :(得分:0)

我会用这样的东西:

output = re.sub(r"\.\./(?=\w)(?!id)", "../Sys/", input)

regex101 demo

请注意,由于有关不应更改内容的信息有限,因此很难找到一个不能替换某些文件路径的信息。正则表达式处理模式,因此没有适当的规则,您必然会发现缺点。

答案 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