How can I do string concatenation, or string repla

2019-01-22 11:58发布

问题:

I have this:

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

How could I use the user_dir for user_pics? If I have to specify other properties like this, it would not be very DRY.

回答1:

You can use a repeated node, like this:

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

I don't think you can concatenate though, so this wouldn't work:

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


回答2:

It's surprising, since the purpose of YAML anchors & references is to factor duplication out of YAML data files, that there isn't a built-in way to concatenate strings using references. Your use case of building up a path name from parts is a good example -- there must be many such uses.

Fortunately there's a simple way to add string concatenation to YAML via custom tags in Python.

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]
""")

Which results in:

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

You can add more items to the array, like " " or "-", if the strings should be delimited.



回答3:

If you are using python with PyYaml, joining strings is possible within the YAML file. Unfortunately this is only a python solution, not a universal one:

with os.path.join:

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

with string.join (for completeness sake - this method has the flexibility to be used for multiple forms of string joining:

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


回答4:

I would use an array, then join the string together with the current OS Separator Symbol

like this:

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


回答5:

Seems to me that YAML itself does not define way to do this.

Good news are that YAML consumer might be able to understand variables.
What will use Your YAML?