2012-11-08 20 views
7

首先,聲明:我對YAML不太熟悉。我試圖解析YAML doc文檔轉成鍵值對(請不要擔心,我怎麼做,我已經得到了處理位)pyYAML錯誤「!」在字符串中

我的文件中使用到看起來像:

world: 
    people: 
      name:Suzy 
      address:chez-bob 

然後,有人去改變它。

world: 
    people: 
      name:!$uzy 
      address:chez-bob 

而且我得到這個語法錯誤:

yaml.constructor.ConstructorError: could not determine a constructor for the tag '!$uzy' 

是什麼意思,甚至?我如何去解釋!$只是兩個字符? 我只想要一個字符串鍵和值的字典! 此外,編輯yaml文件不是一個選項。問題必須使用解析器在代碼中解決。

+0

所以是的,我現在意識到了!告訴它構建一個$ uzy,但是,文件的內容不是我關心的。以優雅的方式處理它。我想要它做的就是把!$ uzy當作文本。 – Rokujolady

+0

...也沒有幫助。 – Rokujolady

回答

8

感嘆號是YAML標籤的前綴。解析器必須通過標籤名稱來實現它的構造函數。有一些默認標籤,如!!bool!!int等,甚至一些Python專用標籤,如!!python/tuple

您可以定義自己的構造函數,甚至構造由前綴抓住了多個標籤。通過爲''定義前綴,您可以捕獲所有標籤並忽略它們。您可以從構造函數中返回標籤及其值,直接將其作爲文本處理。

>>> import yaml 
>>> def default_ctor(loader, tag_suffix, node): 
...  print loader 
...  print tag_suffix 
...  print node 
...  return tag_suffix + ' ' + node.value 
... 
>>> yaml.add_multi_constructor('', default_ctor) 
>>> yaml.load(y) 
<yaml.loader.Loader object at 0xb76ce8ec> 
!$uzy 
ScalarNode(tag=u'!$uzy', value=u'') 
{'world': {'people': {'name': '!$uzy', 'address': 'chez-bob'}}} 
>>> 
+0

你能否提供一個更詳細的例子,有一個類似的問題[這裏](http://stackoverflow.com/questions/43081483/write-a-constructor-to-handle-specific-tags-in-ruamel-or- pyyaml) – askb

4

如果值以「!」開頭,則必須用單引號或雙引號將該值括起來;否則它被解釋爲YAML標籤。

world: 
    people: 
      name: "!$uzy" 
      address: chez-bob 
0

這實際上是PyYAML中的一個錯誤。它解釋在name:!$uzy作爲鍵/值分離器:,但它應該僅僅這樣做,如果:後跟一個空間,或者如果前一標量(name)被引用。後續錯誤是應該允許在標量中間的感嘆號被錯誤地解釋爲在標量的開頭,因此引入標籤。

密鑰people的值是字符串name:!$uzy address:chez-bob,並且在其他解析器(包括我作爲其的Python包ruamel.yaml)中正確處理。

+0

對於此問題的修復似乎已合併到PyYAML 2017年初的源代碼中。但自從上一版本是2016年8月和2014年3月之前的版本以來,可能需要幾個月/的PyPI。 – Anthon