如何在YAML中进行字符串连接或字符串替换?

时间:2011-03-30 08:44:15

标签: concatenation yaml

我有这个:

user_dir: /home/user
user_pics: /home/user/pics

我怎样才能将user_dir用于user_pics?如果我必须指定这样的其他属性,它将不会非常干。

7 个答案:

答案 0 :(得分:38)

您可以使用重复的节点,如下所示:

user_dir: &user_home /home/user
user_pics: *user_home

我认为你不能连接,所以不会工作:

user_dir: &user_home /home/user
user_pics: *user_home/pics

答案 1 :(得分:27)

令人惊讶的是,因为YAML的目的是锚定&引用是因为YAML数据文件中的重复因素,没有内置的方法来使用引用连接字符串。从部件构建路径名的用例就是一个很好的例子 - 必须有很多这样的用途。

幸运的是,有一种简单的方法可以通过Python中的自定义标记向YAML添加字符串连接。

import yaml

## define custom tag handler
def join(loader, node):
    seq = loader.construct_sequence(node)
    return ''.join([str(i) for i in seq])

## register the tag handler
yaml.add_constructor('!join', join)

## using your sample data
yaml.load("""
user_dir: &DIR /home/user
user_pics: !join [*DIR, /pics]
""")

结果是:

{'user_dir': '/home/user', 'user_pics': '/home/user/pics'}

如果字符串应该分隔,您可以向数组中添加更多项目,例如" ""-"

答案 2 :(得分:10)

如果您在PyYaml中使用python,则可以在YAML文件中加入字符串。不幸的是,这只是一个python解决方案,而不是一个普遍的解决方案:

os.path.join

user_dir: &home /home/user
user_pics: !!python/object/apply:os.path.join [*home, pics]

string.join(为了完整起见 - 此方法可以灵活地用于多种形式的字符串连接:

user_dir: &home /home/user
user_pics: !!python/object/apply:string.join [[*home, pics], /]

答案 3 :(得分:6)

我会使用数组,然后将字符串与当前的OS分隔符符号

连接在一起 像这样:

default: &default_path "you should not use paths in config"
pictures:
  - *default_path
  - pics

答案 4 :(得分:3)

我觉得YAML本身does not define way to do this

好消息是YAML消费者可能能够理解变量 什么会使用你的YAML?

答案 5 :(得分:0)

string.join()在Python3中不起作用,但是您可以这样定义!join

import functools
import yaml

class StringConcatinator(yaml.YAMLObject):
    yaml_loader = yaml.SafeLoader
    yaml_tag = '!join'
    @classmethod
    def from_yaml(cls, loader, node):
        return functools.reduce(lambda a, b: a.value + b.value, node.value)

c=yaml.safe_load('''
user_dir: &user_dir /home/user
user_pics: !join [*user_dir, /pics]''')
print(c)

答案 6 :(得分:0)

截至2019年8月

要使Chris'解决方案有效,您实际上需要向Loader=yaml.Loader添加yaml.load()。最终,代码将如下所示:

import yaml

## define custom tag handler
def join(loader, node):
    seq = loader.construct_sequence(node)
    return ''.join([str(i) for i in seq])

## register the tag handler
yaml.add_constructor('!join', join)

## using your sample data
yaml.load("""
user_dir: &DIR /home/user
user_pics: !join [*DIR, /pics]
""", Loader=yaml.Loader)

有关进一步的讨论,请参见this GitHub issue