如何使用Nokogiri插入HTML块并匹配插入位置的正确缩进
解决方案
基于Nokogiri的实现方案
- 核心思路:直接通过Nokogiri的节点属性获取插入位置的缩进,手动处理插入内容的缩进后再替换
- 具体实现步骤:
- 先获取目标插入节点的前一个兄弟节点,这个节点通常是包含换行和缩进的文本节点
- 提取该文本节点最后一次换行后的所有空白字符,即为当前插入位置的层级缩进量
- 给待插入HTML的每一行开头拼接上该缩进量,再执行替换操作
- 代码示例:
# 1. 定位目标插入节点 target_node = doc.at_css('#insertHere') # 2. 获取当前位置的缩进量 prev_sibling = target_node.previous_sibling current_indent = if prev_sibling&.text? # 取最后一次换行后的空白字符作为缩进 prev_sibling.text.split("\n").last || '' else '' end # 3. 处理待插入HTML,给每一行补全缩进 insert_content = <<~HTML <table> <tbody> <tr> <td>Hi</td> </tr> </tbody> </table> HTML indented_content = insert_content.lines.map do |line| line.strip.empty? ? line : "#{current_indent}#{line}" end.join # 4. 执行替换 target_node.replace(indented_content)
如果不需要严格保留原有文档其他位置的格式,也可以直接在插入完成后,使用nokogiri-htmlbeautifier这类扩展gem对整个HTML文档做统一格式化,不需要手动处理缩进。
不基于Nokogiri的实现方案
- 核心思路:给插入占位节点添加唯一标识,用正则匹配占位节点所在行的缩进量
- 具体实现步骤:
- 给待插入位置的节点添加唯一自定义属性,比如
data-insert-mark="unique_123",保证该节点单独占一行 - 用正则匹配整个HTML字符串中该属性所在行,提取行首的空白字符作为缩进量
- 给待插入HTML的每一行补全缩进后,替换掉整个占位节点
- 匹配缩进的正则示例:
html_str = File.read('your_html_file.html') # 匹配占位节点所在行的行首缩进 match_result = html_str.match(/^(\s*)<[^>]+data-insert-mark="unique_123"/) current_indent = match_result ? match_result[1] : ''
该方案适合简单场景,无需引入HTML解析依赖,缺点是占位标签不能拆分为多行,否则正则会匹配失败。
内容的提问来源于stack exchange,提问作者stuyam
相关产品推荐
相关产品推荐

