/**
* 统一 HTML/JSON 解析器
* 结合轻量级HTML解析器(lite)和完整HTML解析器(cheerio版本)
* 不依赖 cheerio,使用纯正则表达式实现,同时支持JSONPath解析
*
* 支持的选择器语法:
* - 标签名: div, p, a, img
* - 类选择器: .class-name
* - ID选择器: #id-name
* - 属性选择器: [attr], [attr=value]
* - 组合选择器: div.class, div#id, img:last-of-type
* - 后代选择器: div p (空格分隔)
* - 伪选择器: :eq(n), :first, :last, :eq(-1), :last-of-type, :first-of-type
* - :has(selector) - 匹配包含指定子元素的元素
* - :contains(text) - 匹配包含指定文本的元素
* - 排除语法: p--a (获取p标签内容但排除a标签)
* - 海阔视界语法: && 分隔, Text, Html
*/
(function(global) {
'use strict';
// ============================================
// 常量定义
// ============================================
var URLJOIN_ATTR = /(url|src|href|-original|-src|-play|-url|style)$|^(data-|url-|src-)/;
var SPECIAL_URL = /^(ftp|magnet|thunder|ws):/;
var SELF_CLOSING_TAGS = /^(img|br|hr|input|meta|link|area|base|col|embed|param|source|track|wbr)$/i;
// 解析缓存开关
var PARSE_CACHE = true;
// 不自动加eq下标索引的选择器
var NOADD_INDEX = ':eq|:lt|:gt|:first|:last|:not|:even|:odd|:has|:contains|:matches|:empty|^body$|^#';
// ============================================
// HTML 元素类
// ============================================
function HtmlElement(tagName, attributes, innerHTML, outerHTML) {
this.tagName = (tagName || '').toLowerCase();
this.attributes = attributes || {};
this.innerHTML = innerHTML || '';
this.outerHTML = outerHTML || '';
}
HtmlElement.prototype.attr = function(name) {
if (!name) return '';
var lowerName = name.toLowerCase();
return this.attributes[name] || this.attributes[lowerName] || '';
};
HtmlElement.prototype.text = function() {
return this.innerHTML
.replace(/