gpt4 book ai didi

ruby - 如何在 parslet 中定义固定宽度约束

转载 作者:数据小太阳 更新时间:2023-10-29 08:01:50 26 4
gpt4 key购买 nike

我正在调查 parslet写了很多数据导入代码。总的来说,图书馆看起来不错,但我正在努力解决一件事。我们的很多输入文件都是固定宽度的,并且宽度因格式而异,即使实际字段没有。例如,我们可能会得到一个包含 9 个字符货币的文件,而另一个文件包含 11 个字符(或其他)。有谁知道如何在 parslet 原子上定义固定宽度约束?

理想情况下,我希望能够定义一个理解货币的原子(带有可选的美元符号、千位分隔符等...)然后我将能够即时创建一个基于旧的完全等效,只是它正好解析 N 个字符。

parslet 中是否存在这样的组合器?如果没有,自己写一个可能/困难吗?

最佳答案

像这样的东西怎么样......

class MyParser < Parslet::Parser
def initialize(widths)
@widths = widths
super
end

rule(:currency) {...}
rule(:fixed_c) {currency.fixed(@widths[:currency])}


rule(:fixed_str) {str("bob").fixed(4)}
end

puts MyParser.new.fixed_str.parse("bob").inspect

这将失败:

"Expected 'bob' to be 4 long at line 1 char 1"

方法如下:

require 'parslet'

class Parslet::Atoms::FixedLength < Parslet::Atoms::Base
attr_reader :len, :parslet
def initialize(parslet, len, tag=:length)
super()

raise ArgumentError,
"Asking for zero length of a parslet. (#{parslet.inspect} length #{len})" \
if len == 0

@parslet = parslet
@len = len
@tag = tag
@error_msgs = {
:lenrep => "Expected #{parslet.inspect} to be #{len} long",
:unconsumed => "Extra input after last repetition"
}
end

def try(source, context, consume_all)
start_pos = source.pos

success, value = parslet.apply(source, context, false)

return succ(value) if success && value.str.length == @len

context.err_at(
self,
source,
@error_msgs[:lenrep],
start_pos,
[value])
end

precedence REPETITION
def to_s_inner(prec)
parslet.to_s(prec) + "{len:#{@len}}"
end
end

module Parslet::Atoms::DSL
def fixed(len)
Parslet::Atoms::FixedLength.new(self, len)
end
end

关于ruby - 如何在 parslet 中定义固定宽度约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5540297/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com