340

In a config file, I have a key to which I wish to assign a URL. The problem is that YAML interprets : and - characters as either creating mappings or lists, so it has a problem with the line

url: http://www.example-site.com/

(both because of the colon following http and the hyphen in the middle)

Is there an explicit way to escape ':' and '-' ? Or would it work to just put the whole thing in single quotes and call it a day?

dreftymac
  • 29,742
  • 25
  • 114
  • 177
danieltahara
  • 4,183
  • 3
  • 17
  • 20

8 Answers8

324

Quotes:

"url: http://www.example-site.com/"

To clarify, I meant “quote the value” and originally thought the entire thing was the value. If http://www.example-site.com/ is the value, just quote it like so:

url: "http://www.example-site.com/"
Matijs
  • 3,108
  • 2
  • 26
  • 40
Ry-
  • 209,133
  • 54
  • 439
  • 449
  • 43
    It depends on the parser, apparently. This didn't work with Jekyll YAML. – ptomato Sep 30 '13 at 03:55
  • 1
    YAMLDotNet also renders quotes. – Dr1Ku Nov 19 '13 at 13:54
  • 2
    Nothing better? Because then quotes need to be escaped themselves, which does not solve the problem but simply moves it forward ... – Augustin Riedinger Jan 27 '15 at 14:47
  • @AugustinRiedinger: Is there something wrong with escaping quotes? – Ry- Jan 27 '15 at 17:56
  • 3
    Well, it would be much cooler to have an error-proof document, just like markdown, so the non-tech guys of the team can edit it (Eg. locale files in Rails) without any risk of breaking it! – Augustin Riedinger Jan 28 '15 at 11:00
  • Relevant link about the significance of quotes https://stackoverflow.com/a/22235064/1175496 -- along with that question's OP linking to YAML cookbooks for more reference http://www.yaml.org/YAML_for_ruby.html#double-quoted_strings – The Red Pea Jun 20 '17 at 23:16
  • Doesn't seem to work if the line isn't a key-value pair but rather a list entry. For `- PS4="+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }"`, Travis complains about the colon at `${FUNCNAME[0]}():` (the same with single quotes). – ivan_pozdeev Dec 19 '17 at 02:21
  • 1
    @ivan_pozdeev: The quotes go around the entire string. `- 'PS4="+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }"'` – Ry- Dec 19 '17 at 05:39
263

What also works and is even nicer for long, multiline texts, is putting your text indented on the next line, after a pipe or greater-than sign:

text: >
    Op dit plein stond het hoofdkantoor van de NIROM: Nederlands Indische 
    Radio Omroep

A pipe preserves newlines, a gt-sign turns all the following lines into one long string.

Oliver Salzburg
  • 20,714
  • 18
  • 89
  • 134
Micros
  • 5,538
  • 2
  • 25
  • 33
  • 9
    ...and a newline is added at the end, which is usually not what you want. – equaeghe Mar 23 '15 at 15:55
  • 77
    @equaeghe: You can use `>-` or `|-` in order to prevent this. – dtoux Mar 30 '15 at 18:23
  • 5
    This is a wonderful solution. Completely avoids having to escape other characters in your text. +++90000 points – bennlich Jun 25 '15 at 16:48
  • is it possible to have a list of multilines somehow? I've tried `- >` but the items after the first are ignored. – ffghfgh Jul 01 '15 at 17:05
  • @ffghfgh - I had a list item with a colon in it and worked around it like this: `- | This is some text: with a colon in it!` – Spakman May 25 '16 at 11:19
  • 3
    @ffghfgh - urg! I can't figure out how to format the code properly in the comment and now I can't edit the original comment. Basically, I used a list item with a pipe, like this: `- |` and then on a new line I indented the list item text so that the first character lined up with the pipe. I hope that helps, it worked for me in a Rails 4.2 locale file. – Spakman May 25 '16 at 11:27
  • That works for Ansible too, when using 'when' clause and comparing a var to a string that contains a double colon. – weshouman Apr 07 '19 at 00:59
80

According to the YAML spec, neither the : nor the - should be a problem. : is only a key separator with a space after it, and - is only an array indicator at the start of a line with a space after it.

But if your YAML implementation has a problem with it, you potentially have lots of options:

- url: 'http://www.example-site.com/'
- url: "http://www.example-site.com/"
- url:
    http://www.example-site.com/
- url: >-
    http://www.example-site.com/
- url: |-
    http://www.example-site.com/

There is explicitly no form of escaping possible in "plain style", however.

Steve Bennett
  • 98,925
  • 29
  • 148
  • 200
33

Quotes, but I prefer them on the just the value:

url: "http://www.example.com/"

Putting them across the whole line looks like it might cause problems.

Gringo Suave
  • 27,899
  • 6
  • 81
  • 73
25

Another way that works with the YAML parser used in Jekyll:

title: My Life: A Memoir

Colons not followed by spaces don't seem to bother Jekyll's YAML parser, on the other hand. Neither do dashes.

ptomato
  • 53,897
  • 13
  • 113
  • 159
  • … are character entities part of YAML? And is what Jekyll uses actually YAML? – Ry- Sep 30 '13 at 04:02
  • Jekyll claims to use it: http://jekyllrb.com/docs/frontmatter/ I can't find anything about character entities in the YAML spec, so I suspect Jekyll is aberrant, but I think this answer serves well for people Googling "yaml escape colon" like me ;-) – ptomato Sep 30 '13 at 04:26
6

If you're using @ConfigurationProperties with Spring Boot 2 to inject maps with keys that contain colons then you need an additional level of escaping using square brackets inside the quotes because spring only allows alphanumeric and '-' characters, stripping out the rest. Your new key would look like this:

"[8.11.32.120:8000]": GoogleMapsKeyforThisDomain

See this github issue for reference.

Andy Brown
  • 10,341
  • 2
  • 35
  • 54
6

I came here trying to get my Azure DevOps Command Line task working. The thing that worked for me was using the pipe (|) character. Using > did not work.

Example:

steps:
- task: CmdLine@2
  inputs:
    script: |
      echo "Selecting Mono version..."
      /bin/bash -c "sudo $AGENT_HOMEDIRECTORY/scripts/select-xamarin-sdk.sh 5_18_1"
      echo "Selecting Xcode version..."
      /bin/bash -c "echo '##vso[task.setvariable variable=MD_APPLE_SDK_ROOT;]'/Applications/Xcode_10.2.1.app;sudo xcode-select --switch /Applications/Xcode_10.2.1.app/Contents/Developer"
Hein Andre Grønnestad
  • 6,687
  • 2
  • 32
  • 43
  • 3
    I used same thing in `.gitlab-ci.yml`, but until I needed pipe '|' in script - it fails silently on it :( – Dalibor Feb 25 '20 at 10:58
1

GitHub actions complain about

curl -L -H "Authorization: token ${{ secrets.TOKEN }}"  https://example.com/try.txt

but it's fine when there is no space after colon, like

curl -L -H "Authorization:token ${{ secrets.TOKEN }}"  https://example.com/try.txt
Alex Cohn
  • 54,176
  • 9
  • 103
  • 290
  • Use multi-line commands, either by starting with > or | and then write you command on the next line. – AJenbo Feb 17 '22 at 16:51