You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Bash正则表达式惰性解析HTML中的首个变更列表?

在Bash脚本中解析HTML提取首个变更列表的方法

你现在需要从changes.html里提取最顶部的那个<ol>列表里的<li>内容,之前尝试用Bash正则遇到了问题,我来帮你梳理下问题所在,再给出几个靠谱的解决方案。

先说说你之前脚本的问题

  1. 文件读取方式导致换行丢失:用$(< ~/Documents/outfile.html)读取文件时,Bash会把所有换行符替换成空格,整个HTML变成一长串文本,这就破坏了原本的块结构,正则自然没法正确匹配单个<ol>块。
  2. Bash正则不支持非贪婪匹配:Bash的扩展正则表达式(ERE)不支持.*?这种惰性匹配语法,所以即使你写了.*,它也会贪婪地匹配到最后一个符合条件的位置,导致匹配范围超出第一个列表。
  3. 正则表达式的捕获逻辑问题:你写的(<ol><li>.*</li></ol>)?,在换行丢失的情况下,根本没法精准匹配到第一个列表的内容,所以捕获组是空的。

解决方案

方法1:用sed处理(纯Bash环境可用)

sed是处理文本的常用工具,我们可以用它定位第一个<ol>到</ol>的块,然后提取里面的<li>内容:

sed -n '
/<ol>/,/<\/ol>/ {
    # 跳过<ol>和</ol>本身的行
    /<ol>/! {
        /<\/ol>/! {
            # 提取<li>标签里的文本
            s/.*<li>\(.*\)<\/li>.*/\1/p
        }
    }
    # 遇到第一个</ol>就退出,避免匹配后续列表
    /<\/ol>/q
}
' changes.html

运行这个命令后,就能输出第一个列表里的两行文本:

Recent Text line 1
Recent Text line 2

方法2:用awk处理(同样是系统自带工具)

awk的逻辑更直观,通过标记位来控制是否处理内容:

awk '
# 遇到第一个<ol>时,开启标记并跳过当前行
/<ol>/{flag=1; next}
# 遇到</ol>时直接退出,只处理第一个列表
/<\/ol>/{exit}
# 标记开启且行包含<li>时,提取文本
flag && /<li>/{
    sub(/.*<li>/, "", $0)  # 去掉<li>之前的所有内容
    sub(/<\/li>.*/, "", $0) # 去掉</li>之后的所有内容
    print
}
' changes.html

方法3:用专业HTML解析工具(推荐,更稳定)

正则处理HTML其实是不太靠谱的(比如标签里多了空格、属性就会失效),更推荐用专门的HTML解析工具,比如pup(需要先安装,比如用apt install pup或者brew install pup):

pup 'h2:first-of-type + ol li text{}' changes.html

这个命令通过CSS选择器精准定位:选择第一个<h2>后面紧邻的<ol>里的所有<li>,然后提取它们的文本内容,结果完全符合你的需求,而且不怕HTML格式的小变动。

内容的提问来源于stack exchange,提问作者Alexander Zhak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:25:01