Rebol/Red Parse技术问题:如何在标记间复制含嵌套div的内容
当然可以!在Rebol/Red Parse里处理带嵌套div的标记间内容提取,确实需要针对嵌套结构做特殊处理,不管是通用方法还是针对div嵌套的特定方案,都有可行的实现方式。
通用方法:基于状态追踪与嵌套层级计数
这种方法适合标记位置不固定、嵌套结构类型多样的场景,核心思路是用Parse的状态变量控制是否开启内容捕获,同时用计数器跟踪嵌套元素的层级,避免提前终止捕获。
举个实际的代码例子(以Red为例):
sample-str: {<div> a ; <- mark1 <div> b </div> <div> c </div> d ; <- mark2 </div> <div> e <div> f </div> <div> g </div> h </div>} ; 初始化状态变量 capturing?: false captured: copy "" depth: 0 parse sample-str [ any [ ; 触发捕获:遇到mark1时开启状态 "; <- mark1" (capturing?: true) | ; 终止捕获:遇到mark2时关闭状态 "; <- mark2" (capturing?: false) | ; 捕获区间内的内容,处理div嵌套 capturing?: true [ "<div>" (depth: depth + 1) (append captured "<div>") | "</div>" (depth: depth - 1) (append captured "</div>") | ; 捕获其他任意字符 skip (append captured copy/part index 1) ] | ; 非捕获区间直接跳过 skip ] ] ; 输出捕获到的内容 print captured
这段代码里,capturing?变量控制是否进入捕获模式,depth计数器会跟踪div的嵌套层数——遇到<div>就加1,遇到</div>就减1,确保我们不会把嵌套里的</div>误当成整个区间的结束。所有捕获到的内容会存在captured字符串里。
针对嵌套div场景的特定优化方法
如果你的场景只需要处理div嵌套,且mark1和mark2的位置相对明确,可以直接编写更精准的Parse规则,省去通用状态追踪的冗余逻辑:
sample-str: {<div> a ; <- mark1 <div> b </div> <div> c </div> d ; <- mark2 </div> <div> e <div> f </div> <div> g </div> h </div>} parse sample-str [ ; 先定位到mark1的位置 to "; <- mark1" mark1-start: position ; 跳过mark1本身的字符串 skip (length of "; <- mark1") ; 匹配到mark2之前的内容,同时处理div嵌套 [ any [ "<div>" (depth: depth + 1) | "</div>" (depth: depth - 1) | skip ] "; <- mark2" ] mark2-start: position ] ; 提取mark1和mark2之间的内容 captured: copy/part mark1-start (mark2-start - mark1-start - length of "; <- mark1") print captured
这个方法直接用to定位到mark1,然后用位置标记mark1-start和mark2-start锁定区间,中间的规则专门处理div的嵌套层级,确保不会在嵌套未闭合时提前匹配到mark2。最后通过位置计算提取出中间的内容。
几个注意点
- 如果mark1或mark2的字符串有变体(比如空格差异),可以用更灵活的匹配规则,比如
[";" space "<-" space "mark1"]来替代固定字符串。 - 层级计数器
depth的初始值要根据mark1后的实际HTML结构调整——如果mark1刚好在<div>标签之后,初始depth可能需要设为1。 - Rebol和Red的Parse语法略有差异,比如Rebol中变量初始化可能需要用
set或者不同的赋值方式,调整时注意适配。
内容的提问来源于stack exchange,提问作者user310291
相关产品推荐
相关产品推荐

