Parsing 在PARSE方言中,如何寻找或通过字符集?

Parsing 在PARSE方言中,如何寻找或通过字符集?,parsing,rebol,bitset,Parsing,Rebol,Bitset,首先,我将陈述我的意图:我正在尝试为可能混淆的10位电话号码编写解析规则。因此,想象一下这样的情况:“callmeNOW…555_uuuuuuuuuuu5555!” 我想从维基百科的列表开始。然后我把它们转换成管道分隔的字符串!作为解析规则使用,我向上搜索到 在那之后,我想我应该试着读下10位数字。但我期望的概念验证没有: >> digit: charset "0123456789" == make bitset! #{000000000000FFC0} >> pars

首先,我将陈述我的意图:我正在尝试为可能混淆的10位电话号码编写解析规则。因此,想象一下这样的情况:“callmeNOW…555_uuuuuuuuuuu5555!”

我想从维基百科的列表开始。然后我把它们转换成管道分隔的字符串!作为解析规则使用,我向上搜索

在那之后,我想我应该试着读下10位数字。但我期望的概念验证没有:

>> digit: charset "0123456789"
== make bitset! #{000000000000FFC0}

>> parse "callmeNOW...555___555____5555!" [10 [thru digit] to end]
== false
导致我进行了一项更简单的测试,但未能达到我的目的:

>> parse "5" [thru digit]
== false
如果我不将其与THRU一起使用,则它会执行预期的操作:

>> parse "5" [digit]
== true
为什么比特集用作令牌而不与
TO
THRU
一起使用时受支持


另外,如果有人想要,这里有一个Rebol区块的区号列表


不简洁,但如果我不把我的数字集构造成一个位集!但与管道规则相比,它工作得很好:

>> digit: ["0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"]
== ["0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"]

>> parse "callmeNOW...555___555____5555!" [10 [thru digit] to end]
== true

当然,虽然R3确实会沿着一个位移动
parse
,但通常的模式是创建一个互补的位集,将内容跳过所需的位集

filler: complement digit: charset "0123456789"
parse/all stream [any [copy n some digit (append out: [] n) | some filler]]
probe out   ; all the digit chunks in the stream

真正的答案是TO和THRU不是模式匹配操作符,而是搜索操作符

字符集专门用于模式匹配,因此它们是一个位掩码,因此您无法搜索它们,它们不存在于流中,它们一次过滤和比较一个字节。这并不意味着它们不能在将来用于to/THRU,只是为什么它们到目前为止还不打算用作to/THRU

您的“管道规则”示例之所以有效(实际上是使用OR(“|”)操作的备选方案列表),是因为TO/THRU将按给定顺序搜索每个备选方案,直到其中一个匹配为止(因此,在一长串备选方案中,顺序应改变速度)

以下规则将提取所有格式相对良好的电话号码,以便在表单(R2和R3)中留出一些“回旋余地”:


请注意,以上是一个快速和肮脏的号码提取任何北美电话。它将扫描整个文本,打印找到的任何数字。

Hmmm…有趣的解决方法。虽然它不能回答为什么TO/THRU不能“只工作”!那该死的rebol.c源代码在哪里-/嗯。我用
解析“9876543210”[到数字位置:(打印位置)]
测试了您的案例,得到了9876543210的输出。从数字声明中删除
|“9”
会得到876543210。你看到什么不一样的东西了吗?我在A111上也看到了“9876543210”。看来我错了。你们说得对。奇怪,我记得这是个问题。。。但也许一些解析技巧在我脑海中闪过。我把那张便条从我的帖子上删除了。。。我不希望它在出错时被使用。不过,我要补充的是,随着你越来越习惯于解析,to和THRU变得越来越麻烦而不是有用。我现在很少使用它们,即使是在简单的规则中。。。使用带模式的skip几乎总是更好的解决方案。我感觉到的唯一真正的麻烦是TO和THRU不工作的频率!他们通常简洁地表达我想要的东西。如果我们得到了这个消息来源,我会看一看,更好地了解为什么事情“是这样的”。
filler: complement digit: charset "0123456789"
parse/all stream [any [copy n some digit (append out: [] n) | some filler]]
probe out   ; all the digit chunks in the stream
digit: charset "0123456789"
!digit: complement digit

parse/all text [   
    any [ 
        copy phone [ opt "(" 3 digit    1 3 !digit   3 digit    1 3 !digit    4 digit] (print phone)  
        |  skip 
    ] 
]