红色解析与休息

时间:2018-04-30 09:48:45

标签: rebol red

我的解析代码中断了没有用,我不应该在文本中得到最后一个div块:

src: {
<div class="main">
    <div>
        test
    </div>

    <div>
        test2
    </div>
    <div>
        test3
    </div>
</div>

<div class="test">
</div>
}

rules: [
    (div-count: 0)
    some [
        to "<div"
        (div-count: div-count + 1) [if (div-count = 1) mark1:] 
        |
        thru "</div>"
        (div-count: div-count - 1) [if (div-count = 0) mark2: break]
    ]

    text: copy/part mark1 mark2

]

parse src rules
print text

我想要的预期结果是:

    {
    <div class="main">
        <div>
            test
        </div>

        <div>
            test2
        </div>
        <div>
            test3
        </div>
    </div>
    }

2 个答案:

答案 0 :(得分:1)

Red和Rebol的答案看起来像这样

rules: [
    (div-count: 0   clear rules/3/8 )
    some [
        mark:  "<div"  
        (if  equal? 1  div-count: div-count + 1  [
            mark1:  mark  
        ] )   | 
         "</div>"  mark2:
        ( 
        if equal? 0  div-count: div-count - 1  [
            text: copy/part mark1 mark2    
            insert rules/3/8 [to end]  
        ]  )  
        [] | skip
    ]
]

您的规则存在的一个问题是您使用 to |(含义或) thru ,所以大多数结束</div>将被跳过。第一个匹配<div已满足,并且在未与下列子规则进行比较的情况下进入下一个开始<div。但是光标没有前进,下一个<div仍然是相同的。可能红色发现无限循环(没有前进)并中断它。

我使用动态修改的规则而不是break,因为break突破了Rebol中的(子)规则,但并没有像你在这里看到的那样停止整个解析过程。

 >> parse "aaa" [(n: 0)some ["a" [break] (ask form n: n + 1) ]]
 1
 2
 3
 == true

这与Red不同,它会在中断解析。

>> parse "aaa" [(n: 0)some ["a" [break] (ask form n: n + 1) ]]
1
== false

所以一个适合Red的简单解决方案,而不是Rebol可以看起来像

rules: [
    (div-count: 0)
    some [
        mark: "<div"
        (if  equal? 1  div-count: div-count + 1  [mark1:  mark]) 
        |
        "</div>" mark2:
        if (equal? 0  div-count: div-count - 1 )  
          [(print text: copy/part mark1 mark2 )  break]
        |
        skip
    ]
]

答案 1 :(得分:1)

以下是解析它的另一种参数化方法:

div: ["<div" 4 skip some ["</div>" break | div | skip] | skip]
div-rule: [to "<div" div]

n: 1
parse src compose [(n - 1) div-rule copy text div-rule to end]

使用n: 1,它将提取第一个根<div>,其中n: 2,第二个根,等等。应该也可以参数化嵌套规则以提取任意<div>部分。