Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 如何使用带字符串的欧芹而不是欧芹切片_Ruby_Parslet - Fatal编程技术网

Ruby 如何使用带字符串的欧芹而不是欧芹切片

Ruby 如何使用带字符串的欧芹而不是欧芹切片,ruby,parslet,Ruby,Parslet,我已经开始使用欧芹来解析一些自定义数据。在示例中,生成的解析数据类似于: { :custom_string => "data"@6 } 我已经创建了类似这样的转换 rule(:custom_string => simple(:x)) { x.to_s } 但它不匹配,大概是因为我传递的是“data”@6,而不仅仅是“data”,这不仅仅是一个简单的字符串。所有用于转换的函数都有带字符串的散列,而不是解析器输出的Parslet::Slices。也许我漏了一步,但我在文件里什么都看不

我已经开始使用欧芹来解析一些自定义数据。在示例中,生成的解析数据类似于:

{ :custom_string => "data"@6 }
我已经创建了类似这样的转换

rule(:custom_string => simple(:x)) { x.to_s }
但它不匹配,大概是因为我传递的是“data”@6,而不仅仅是“data”,这不仅仅是一个简单的字符串。所有用于转换的函数都有带字符串的散列,而不是解析器输出的Parslet::Slices。也许我漏了一步,但我在文件里什么都看不见

编辑:更多示例代码(简化版,但仍应解释)

original_text='MSGSTART/DATA1/DATA2/0503/MAR'
需要“欧芹”
包括欧芹
模块解析示例
类解析器>fs>>data1>>fs>>data2>>fs>>序列号>>fs>>month>>newline}
规则(:document){first_line>>newline.maybe}
根目录(:文档)
结束
结束
模块解析示例
类转换器simple(:x)){x.to_s}
规则(:data2=>simple(:x)){x.to_s}
规则(:serial_number=>simple(:x)){x.to_s}
规则(:month=>simple(:x)){x.to_s}
结束
结束
#通过调用运行。。。
p=ParseExample::Parser.new
解析结果=p.parse(原始文本)
#=>{:data1=>“data1”@6,:data2=>“data2”@12,:serial_number=>“0503”@18,:month=>“MAR”@23}
t=ParseExample::Transformer.new
transformed=t.apply(解析器\结果)
#实际结果=>{:data1=>“data1”@6,:data2=>“data2”@12,:serial_number=>“0503”@18,:month=>“MAR”@23}
#预期结果=>{:data1=>“data1”,:data2=>“data2”,:serial_number=>“0503”,:month=>“MAR”}

不能替换单个键/值对。您必须立即替换整个哈希。

我第一次写《变形金刚》时也爱上了这个。关键是转换规则匹配整个节点并替换它。。就整体而言。一旦节点已匹配,就不会再次访问它

如果您确实使用了散列,并且只匹配一个键/值对,请将其替换为一个值。。。您刚刚在同一个散列中丢失了所有其他键/值对

但是。。。有办法

如果您确实希望在匹配整个散列之前预处理散列中的所有节点,则散列的值需要是散列本身。然后,您可以匹配这些值并将它们转换为字符串。通常只需在解析器中添加另一个'as'即可

例如:
original_text='MSGSTART/DATA1/DATA2/0503/MAR'
需要“欧芹”
包括欧芹
模块解析示例
类解析器>fs>>
数据1>>fs>>
数据2>>fs>>
序列号>>fs>>
月>>新线。也许吧
}
规则(:document){first_line>>newline.maybe}
根目录(:文档)
结束
结束
#通过调用运行。。。
p=ParseExample::Parser.new
parser\u result=p.parse(原始文本)
将语法分析器放入result.inspect
#=>{:data1=>{:string=>“data1”@9},
:data2=>{:string=>“data2”@15},
:serial_number=>{:string=>“0503”@21},
:month=>{:string=>“MAR”@26}
#看看散列中的值现在如何都是散列本身。
模块解析示例
类转换器simple(:x)){x.to_s}
结束
结束
#我们现在只需要匹配“{:string=>x}”散列…并用字符串替换它们
t=ParseExample::Transformer.new
transformed=t.apply(解析器\结果)
检查
#=>{:data1=>“data1”,:data2=>“data2”,:serial_number=>“0503”,:month=>“MAR”}
#多田!!!
如果你想处理整条线,一定要用它做一个物体。。说

class Entry 
   def initialize(data1:, data2:, serial_number:,month:)
      @data1 = data1
      @data2 = data2
      @serial_number = serial_number
      @month = month
   end
end

module ParseExample
  class Transformer < Parslet::Transform
    rule(:string => simple(:x)) { x.to_s }

    # match the whole hash
    rule(:data1 => simple(:d1),
         :data2 => simple(:d2),
         :serial_number => simple(:s),
         :month => simple(:m)) { 
            Entry.new(data1: d1,data2: d2,serial_number: s,month: m)} 
  end
end

t = ParseExample::Transformer.new
transformed = t.apply(parser_result)

puts transformed.inspect
# => #<Entry:0x007fd5a3d26bf0 @data1="DATA1", @data2="DATA2", @serial_number="0503", @month="MAR">
类条目
def初始化(数据1:,数据2:,序列号:,月份:)
@数据1=数据1
@数据2=数据2
@序列号=序列号
@月=月
结束
结束
模块解析示例
类转换器simple(:x)){x.to_s}
#匹配整个散列
规则(:data1=>simple(:d1),
:data2=>简单(:d2),
:serial_number=>simple(:s),
:month=>simple(:m)){
Entry.new(数据1:d1,数据2:d2,序列号:s,月份:m)}
结束
结束
t=ParseExample::Transformer.new
transformed=t.apply(解析器\结果)
检查
# => #

Transformers同时处理哈希和解析器返回的对象树。所以一定是出了什么问题。请发布更多代码,以便我们能够发现问题。感谢Nigel的大力帮助。那真是一种享受。
original_text = 'MSGSTART/DATA1/DATA2/0503/MAR'

require "parslet"
include Parslet

module ParseExample
  class Parser < Parslet::Parser
    rule(:fs)         { str("/") }
    rule(:newline)    { str("\n") | str("\r\n") }

    rule(:msgstart) { str("MSGSTART") }

    rule(:string) {match("\\w").repeat(1).as(:string)} # Notice the as!

    rule(:data1) { string.as(:data1) }
    rule(:data2) { string.as(:data2) }
    rule(:serial_number) { string.as(:serial_number) }
    rule(:month) { string.as(:month) }

    rule(:first_line) { 
        msgstart >> fs >> 
        data1 >> fs >> 
        data2 >> fs >> 
        serial_number >> fs >> 
        month >> newline.maybe 
    }

    rule(:document) { first_line >> newline.maybe }

    root(:document)
  end
end

# Run by calling...
p = ParseExample::Parser.new
parser_result = p.parse(original_text)

puts parser_result.inspect
# => {:data1=>{:string=>"DATA1"@9}, 
      :data2=>{:string=>"DATA2"@15}, 
      :serial_number=>{:string=>"0503"@21}, 
      :month=>{:string=>"MAR"@26}}

# See how the values in the hash are now all hashes themselves.

module ParseExample
  class Transformer < Parslet::Transform
    rule(:string => simple(:x)) { x.to_s }
  end
end

# We just need to match the "{:string => x}" hashes now...and replace them with strings

t = ParseExample::Transformer.new
transformed = t.apply(parser_result)

puts transformed.inspect
# => {:data1=>"DATA1", :data2=>"DATA2", :serial_number=>"0503", :month=>"MAR"}

# Tada!!!
class Entry 
   def initialize(data1:, data2:, serial_number:,month:)
      @data1 = data1
      @data2 = data2
      @serial_number = serial_number
      @month = month
   end
end

module ParseExample
  class Transformer < Parslet::Transform
    rule(:string => simple(:x)) { x.to_s }

    # match the whole hash
    rule(:data1 => simple(:d1),
         :data2 => simple(:d2),
         :serial_number => simple(:s),
         :month => simple(:m)) { 
            Entry.new(data1: d1,data2: d2,serial_number: s,month: m)} 
  end
end

t = ParseExample::Transformer.new
transformed = t.apply(parser_result)

puts transformed.inspect
# => #<Entry:0x007fd5a3d26bf0 @data1="DATA1", @data2="DATA2", @serial_number="0503", @month="MAR">