请考虑以下事项:
>> bin: to-binary {Rebol}
== #{5265626F6C}
>> parse/all bin [s: to end]
== true
我希望s
已经捕获了二进制序列的头部,并且是BINARY类型!在Rebol 3中就是这种情况:
>> type? s
== binary!
>> s == bin
== true
在Rebol 2中,似乎解析必须将数据转换为字符串(或至少将二进制“映射”为字符串!在引擎盖下,而不是比较相等)
>> type? s
== string!
>> s == bin
== false
因为Rebol 2不是Unicode,所以二进制字节字符串和字符串基本相同。但是对于Rebol 3的Unicode我猜测,如果你写了:
,你可能会遇到非常不同的行为parse/all to-string bin [s: to end]
因为它会开始将多个字节序列解释为字符串编码,如果您真正想要的是未解释的字节,则这不起作用。 : - (
如果想要在解析BINARY的同时编写适用于Rebol 2或Rebol 3的代码,你会如何解决这个问题? (理想情况下,当然Rebol 2的行为更像是3)。
答案 0 :(得分:2)
事实上,Rebol 2实际上只是将数据“成像”为一个STRING!而不是复制它,请注意以下
>> bin: to-binary {Rebol}
== #{5265626F6C}
>> parse bin [s: (clear s)]
== true
>> s
== ""
>> bin
== #{}
这是因为Rebol 2有可用于将字符串数据别名为二进制的例程,反之亦然:AS-BINARY和AS-STRING。与他们的TO-BINARY和TO-STRING变体不同,它们实际上并不复制数据。
这是一个想法,你(嗯,我,我)可以尝试...制作兼容性功能(让我们称之为bin-pos
):
bin-pos: func [pos [binary! string!]] [
return either string? pos [
;; we must be using r2, image the parse position back to binary
as-binary pos
] [
;; just a no-op in r3, binary parse input yields binary parse positions
pos
]
]
所以在上面的示例中,对于Rebol 2来说,正确的事情发生了,如果您使用s
替换bin-pos s
,则替换>> type? (bin-pos s)
== binary!
>> (bin-pos s) == bin
== true
:
bin-capture
对于使用COPY方言词并且创建新字符串的情况,相同的技术将起作用......但是可能应该使用不同的包装器名称。 {{1}}?
答案 1 :(得分:0)
您只需在规则中添加一个解析操作,以确保捕获的数据为binary!
:
>> bin: to binary! {Rebol}
>> parse/all bin [s: to end (s: to binary! s)]
>> type? s
== binary!
您可以将此转换包装在ensure-binary
帮助程序中以用于文档目的。
(请注意,如果我理解你的答案的最后一段,这基本上就是你在那里建议的。但是,我认为你可以使用这种方法,即使对于没有copy
的捕获也是如此。)