Как мне разобрать YAML с нулевыми значениями? - PullRequest
3 голосов
/ 20 августа 2009

Я прошу прощения за очень конкретную проблему, которую я публикую здесь, но я надеюсь, что это поможет другим, которые также могут столкнуться с этой проблемой. У меня есть строка, которая форматируется в следующем:

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

Я хотел бы перевести это на действительный YAML, чтобы его можно было проанализировать, что бы выглядело так:

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

Я пробовал кучу регулярных выражений для достижения этой цели, но я боюсь, что я в полной растерянности. Я в порядке с запуском нескольких выражений, если это необходимо. Например (рубин): ​​

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

Это уже там, но у меня такое чувство, что я начинаю спускаться с крысы при таком подходе. Есть ли лучший способ сделать это?

Спасибо за помощь!

Ответы [ 3 ]

4 голосов
/ 20 августа 2009

Это делает работу для пустых полей (ruby1.9):

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

Или для ruby1.8, который не поддерживает просмотр нулевой ширины:

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

Заключение в кавычки непустых полей может быть сделано с одним из них:

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

В приведенном выше примере я использую положительный взгляд нулевой ширины и утверждения положительного просмотра нулевой ширины ('(? <=' И '(? ='). </p>

Я искал некоторую документацию по рубину, но не смог найти ничего, что конкретно объясняет эти функции. Вместо этого, позвольте мне отослать вас к perlre .

3 голосов
/ 20 августа 2009

Было бы проще просто разобрать его, а затем вывести действительный YAML.


Так как я не знаю Ruby, вот пример на Perl.


Поскольку вам требуется только подмножество YAML, которое похоже на JSON, я использовал модуль JSON.

Я давно хотел найти оправдание для использования Regexp::Grammars, поэтому я использовал его для анализа данных.

Я гарантирую, что это будет работать, независимо от того, насколько глубоки массивы.

#! /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
- []
-
  - ''
  - ''
-
  - ''
  - []
  - ''
1 голос
/ 20 августа 2009

Попробуйте это:

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

РЕДАКТИРОВАТЬ: я не уверен насчет синтаксиса замены. Предполагается, что это будет группа № 1 в первом gsub, а группа-участник с наибольшим номером - $+ - во втором.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...