如何解析带有 nil 值的 YAML?

发布于 2024-08-02 04:26:24 字数 546 浏览 7 评论 0原文

对于我在这里发布的非常具体的问题,我深表歉意,但我希望它能帮助其他也可能遇到此问题的人。 我有一个正在格式化为以下内容的字符串:

[[,action1,,],[action2],[]]

我想将其转换为有效的 YAML,以便可以解析它,如下所示:

[['','acton1','',''],['action2'],['']]

我已经尝试了一堆正则表达式来完成此操作,但我担心我完全不知所措。 如果需要的话,我可以运行多个表达式。 例如(ruby):

puts s.gsub!(/,/,"','")  # => [[','action1','',']','[action2]','[]]
puts s.gsub!(/\[',/, "['',") # => [['','action1','',']','[action2]','[]]

就这样,但我有一种感觉,我开始用这种方法陷入困境。 有更好的方法来实现这一点吗?

谢谢您的帮助!

I apologize for the very specific issue I'm posting here but I hope it will help others that may also run across this issue. I have a string that is being formatted to the following:

[[,action1,,],[action2],[]]

I would like to translate this to valid YAML so that it can be parsed which would look like this:

[['','acton1','',''],['action2'],['']]

I've tried a bunch of regular expressions to accomplish this but I'm afraid that I'm at a complete loss. I'm ok with running multiple expressions if needed. For example (ruby):

puts s.gsub!(/,/,"','")  # => [[','action1','',']','[action2]','[]]
puts s.gsub!(/\[',/, "['',") # => [['','action1','',']','[action2]','[]]

That's getting there, but I have a feeling I'm starting to go down a rat-hole with this approach. Is there a better way to accomplish this?

Thanks for the help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

不语却知心 2024-08-09 04:26:25

这可以完成空字段(ruby1.9)的工作:

s.gsub(/(?<=[\[,])(?=[,\]])/, "''")

或者对于 ruby​​1.8,它不支持零宽度后视:

s.gsub(/([\[,])(?=[,\]])/, "\\1''")

可以使用以下之一来完成引用非空字段:

s.gsub(/(?<=[\[,])\b|\b(?=[,\]])/, "'")
s.gsub(/(\w+)/, "'\\1'")

在上面我'我使用零宽度正向后向断言和零宽度正向前向断言('(?<=' 和 '(?=')。

我查找了一些 ruby​​ 特定文档,但找不到任何相反,请让我参考 perlre

This does the job for the empty fields (ruby1.9):

s.gsub(/(?<=[\[,])(?=[,\]])/, "''")

Or for ruby1.8, which doesn't support zero-width look-behind:

s.gsub(/([\[,])(?=[,\]])/, "\\1''")

Quoting non-empty fields can be done with one of these:

s.gsub(/(?<=[\[,])\b|\b(?=[,\]])/, "'")
s.gsub(/(\w+)/, "'\\1'")

In the above I'm making use of zero-width positive look behind and zero-width positive look ahead assertions (the '(?<=' and '(?=').

I've looked for some ruby specific documentation but could not find anything that explains these features in particular. Instead, please let me refer you to perlre.

赴月观长安 2024-08-09 04:26:25

直接解析它,然后输出有效的 YAML 会更容易。


由于我不懂 Ruby,这里有一个 Perl 的例子。


由于您只需要 YAML 的子集(看起来与 JSON 类似),因此我使用了 JSON 模块。

我一直想要一个使用 Regexp::Grammars< 的借口/a>,所以我用它来解析数据。

我保证它会起作用,无论数组有多深。

#! /usr/bin/env perl
use strict;
#use warnings;
use 5.010;
#use YAML;
use JSON;
use Regexp::Grammars;


my $str = '[[,action1,,],[action2],[],[,],[,[],]]';

my $parser = qr{
  <match=Array>

  <token: Text>
    [^,\[\]]*

  <token: Element>
  (?:
    <.Text>
  |
    <MATCH=Array>
  )

  <token: Array>
  \[
     (?:
       (?{ $MATCH = [qw'']; })
     |
       <[MATCH=Element]>   ** (,)
     )
  \]
}x;


if( $str =~ $parser ){
  say to_json $/{match};
}else{
  die $@ if $@;
}

哪个输出。

[["","action1","",""],["action2"],[],["",""],["",[],""]]

如果您确实想要 YAML,只需取消注释“use YAML;”,并将 to_json() 替换为 Dump()

---
-
  - ''
  - action1
  - ''
  - ''
-
  - action2
- []
-
  - ''
  - ''
-
  - ''
  - []
  - ''

It would be easier to just parse it, then output valid YAML.


Since I don't know Ruby, Here is an example in Perl.


Since you only want a subset of YAML, that appears to be similar to JSON, I used the JSON module.

I've been wanting an excuse to use Regexp::Grammars, so I used it to parse the data.

I guarantee it will work, no matter how deep the arrays are.

#! /usr/bin/env perl
use strict;
#use warnings;
use 5.010;
#use YAML;
use JSON;
use Regexp::Grammars;


my $str = '[[,action1,,],[action2],[],[,],[,[],]]';

my $parser = qr{
  <match=Array>

  <token: Text>
    [^,\[\]]*

  <token: Element>
  (?:
    <.Text>
  |
    <MATCH=Array>
  )

  <token: Array>
  \[
     (?:
       (?{ $MATCH = [qw'']; })
     |
       <[MATCH=Element]>   ** (,)
     )
  \]
}x;


if( $str =~ $parser ){
  say to_json $/{match};
}else{
  die $@ if $@;
}

Which outputs.

[["","action1","",""],["action2"],[],["",""],["",[],""]]

If you really wanted YAML, just un comment "use YAML;", and replace to_json() with Dump()

---
-
  - ''
  - action1
  - ''
  - ''
-
  - action2
- []
-
  - ''
  - ''
-
  - ''
  - []
  - ''
孤芳又自赏 2024-08-09 04:26:25

试试这个:

s.gsub(/([\[,])(?=[,\]])/, "\\1''")
 .gsub(/([\[,])(?=[^'\[])|([^\]'])(?=[,\]])/, "\\+'");

编辑:我不确定替换语法。这应该是第一个 gsub 中的组 #1,以及第二个中编号最高的参与组 - $+

Try this:

s.gsub(/([\[,])(?=[,\]])/, "\\1''")
 .gsub(/([\[,])(?=[^'\[])|([^\]'])(?=[,\]])/, "\\+'");

EDIT: I'm not sure about the replacement syntax. That's supposed to be group #1 in the first gsub, and the highest-numbered participating group -- $+ -- in the second.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文