Red语言中带break的parse代码异常:不应获取最后一个div块
我来帮你分析这个Parse代码的问题所在,以及如何修复它。
核心问题:分支顺序导致闭合标签被跳过
你的规则里最大的问题是分支顺序错误:你优先使用了to "<div"来匹配下一个div起始标签,这会导致代码跳过中间的</div>闭合标签(包括.main的闭合标签),让嵌套计数div-count永远无法回到0,break也就永远不会触发,最终代码会继续处理后面的.test div,导致结果不符合预期。
举个具体的场景:当处理完test3的</div>后,当前位置在这个闭合标签之后,下一个是.main的</div>,但你的规则会优先执行to "<div",直接跳过.main的闭合标签和中间的空格,匹配到后面的<div class="test">,这就完全错过了.main的闭合处理,div-count一直停留在1,永远不会触发break。
修复方案
我们只需要调整分支顺序,优先处理</div>闭合标签,确保嵌套计数能正确递减,在回到0时及时终止循环:
src: {<div class="main"> <div> test </div> <div> test2 </div> <div> test3 </div> </div> <div class="test"> </div>} rules: [ (div-count: 0) some [ ; 先处理闭合标签,避免被跳过 thru "</div>" (div-count: div-count - 1) [ if div-count = 0 [ mark2: break ] ] | ; 再处理起始标签 to "<div" (div-count: div-count + 1) [ if div-count = 1 [ mark1: ] ] ] text: copy/part mark1 mark2 ] parse src rules print text
运行这段代码,你会得到预期的结果:<div class="main"> <div> test </div> <div> test2 </div> <div> test3 </div> </div>,不会包含后面的.test div。
更精准的优化(可选)
如果你只想获取.main div的内部内容(不包含.main自身的标签),可以先精准定位到.main的起始标签,再处理嵌套:
src: {<div class="main"> <div> test </div> <div> test2 </div> <div> test3 </div> </div> <div class="test"> </div>} rules: [ ; 精准定位到目标div的起始标签 to "<div class=\"main\">" ; 标记内部内容的起始位置(跳过起始标签) mark1: skip (div-count: 1) ; 已经进入main div,计数初始为1 some [ thru "</div>" (div-count: div-count - 1) [ if div-count = 0 [ mark2: break ] ] | thru "<div" (div-count: div-count + 1) ] ; 复制内部内容(从main标签后到闭合标签前) text: copy/part mark1 back mark2 ] parse src rules print text
这段代码会输出:<div> test </div> <div> test2 </div> <div> test3 </div>,完全是.main的内部内容。
内容的提问来源于stack exchange,提问作者user310291

