带中断的红色解析
Red parse with break
我的带有 break 的解析代码不起作用,我不应该在文本中得到最后一个 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>
}
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
这与红色不同,它会中断解析。
>> 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
]
]
这是解析它的另一种参数化方法:
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>
部分。
我的带有 break 的解析代码不起作用,我不应该在文本中得到最后一个 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>
}
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
这与红色不同,它会中断解析。
>> 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
]
]
这是解析它的另一种参数化方法:
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>
部分。