^  <!-- 匹配开头。暂时忽略 html、head 之类的标签 -->
<body style=any>  <!-- 样式任意 -->
  <header any*> <any** any*/> </header>  <!-- 任意个属性、后代节点(属性任意) -->
  <div class="container">
    <any** any*>  <!-- 忽略中间若干层节点。类似 xpath 中的 // -->
      (?<帖子列表>  <!-- 类似 js 正则中的命名捕获组 -->
      <ul class="topic-ul">  <!-- 帖子列表 -->
        <li>
          (?<用户信息>
          <div class="topic-anchor">
            <a href=text>
              <img class="avatar" src=(?<头像URL> text ) />
            </a>
            <a href=(?<链接> text )> (?<名称> text ) </a>
          </div>)
          (?<帖子信息>
          <div class="topic-title">
            <a class="user-title" href=(?<链接> text )>
              (?<标题> text )
            </a>
            <div class="topic-meta">
              (?<点击数> text ) "点击 / "
              (?<发布时间> text ) "发布 / "
              (?<最新回复时间> text ) "回复"
            </div>
          </div>
          <div class="topic-reply-count">
            <a href=text> (?<回复数> text ) </a>
          </div>
          (?<板块信息>
          <div class="topic-forum-name">
            <a class="topic-title" href=(?<链接> text) >
              (?<名称> text )
            </a>
          </div>))
        </li> +  <!-- 至少一个帖子 -->
      </ul>)
    </any**>
  </div>
  <any** any*/>  <!-- 不关心后续节点 -->
</body>
$  <!-- 匹配结尾 -->
捕获结果:
[
  {
    "用户信息": {
      "头像URL": "https://file.hu60.cn/avatar/19011.jpg?r=1652530427",
      "链接": "https://hu60.cn/q.php/user.info.19011.html",
      "名称": "花祭"
    },
    "帖子信息": {
      "链接": "https://hu60.cn/q.php/bbs.topic.105334.html",
      "标题": "我这5g这么慢",
      "点击数": "160",
      "发布时间": "08-31 08:15",
      "最新回复时间": "11分钟前",
      "回复数": "12"
    },
    "板块信息": {
      "链接": "https://hu60.cn/q.php/bbs.forum.88.html",
      "名称": "超级灌水"
    }
  },
  {
    "用户信息": {
      "头像URL": "https://file.hu60.cn/avatar/24826.jpg?r=1692886310",
      "链接": "https://hu60.cn/q.php/user.info.24826.html",
      "名称": "咯叽"
    },
    "帖子信息": {
      "链接": "https://hu60.cn/q.php/bbs.topic.105341.html",
      "标题": "qq浏览器有何神奇之处?",
      "点击数": "10",
      "发布时间": "1小时前",
      "最新回复时间": "45分钟前",
      "回复数": "4"
    },
    "板块信息": {
      "链接": "https://hu60.cn/q.php/bbs.forum.88.html",
      "名称": "超级灌水"
    }
  },
  "……省略剩余 18 个帖子信息……"
]
比如,有些帖子有 [公开] 标签,能不能自动识别加上呢?
<div class="topic-meta">
    (?<点击数> text ) "点击 / "
    (?<发布时间> text ) "发布 / "
    (?<最新回复时间> text ) "回复"
    <div class="topic-status">"公开"</div> ?  <!-- 自动备注:出现了 4 / 20 次 -->
</div>
querySelector的nodejs版本:
https://www.npmjs.com/package/query-selector
PHP版:https://symfony.com/doc/current/components/dom_crawler.html
If you prefer CSS selectors over XPath, install The CssSelector Component. It allows you to use jQuery-like selectors:
$crawler = $crawler->filter('body > p');
XSLTJSON: Transforming XML to JSON using XSLT
https://github.com/bramstein/xsltjson
XSLT是一种样式表,用于把XML转换为其他表现形式(比如可显示的HTML,甚至是JSON)。该样式表也可以用于验证输入是否与样式匹配。
不过HTML不是严格的XML,不清楚解析器是否能正确处理HTML中的宽松语法。
@无名啊,搜“XSLT html to json”可以看到一些案例。
比如这个:
https://stackoverflow.com/questions/18055368/html-to-json-conversion-in-xslt
虽然 XSLT 最初被设计为用于 XML 转换的专用语言,但该语言是图灵完备的,这使得它理论上能够进行任意计算。
XSLT 2.0 最重要的创新包括:
使用正则表达式进行字符串操作
XSLT 3.0
支持映射和数组,使 XSLT 能够处理 JSON 和 XML。
改进了对动态错误的处理,例如使用 xsl:try 指令。
https://en.m.wikipedia.org/wiki/XSLT
@无名啊,也许看看这个,对你的语法定义有启发:https://juejin.cn/post/7281474941257973816
不如直接使用 jsx 生态,表达能力不错,还能嵌入逻辑,解析器工具链也都比较完善
@老虎会游泳,以前碰到过类似情况吗?有啥好用的工具吗?