diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeByJSonPath.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeByJSonPath.kt index b45b89643..63e02ec8c 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeByJSonPath.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeByJSonPath.kt @@ -1,33 +1,192 @@ -0. 新增专门用于切分各种规则的类,分解完所有规则后才切片,其余操作都只改变变量指向规则字符串中的位置。暂时只用于处理三大规则的“&&”、“||”,“%%”、“@”切分,以后将扩展到全部解析规则。 - - 改进jsonPath,jsoup,xpath中的规则切分方法,允许查询规则的正则或字符串中存在“&&”,“||”,“%%”,“@”而不切错。 - -/** -* 改进解析方法 -* 解决阅读”&&“、”||“与jsonPath支持的”&&“、”||“之间的冲突 -* 解决{$.rule}形式规则可能匹配错误的问题,旧规则用正则解析内容含‘}’的json文本时,用规则中的字段去匹配这种内容时,会匹配错误.现改用平衡嵌套方法解决这个问题 -* */ - -1. 加强AnalyzeByJSoup中的索引写法 - -/** -* 1.支持阅读原有写法,':'分隔索引,!或.表示筛选方式,索引可为负数 -* -* 例如 tag.div.-1:10:2 或 tag.div!0:3 -* -* 2. 支持与jsonPath类似的[]索引写法 -* -* 格式形如 [it,it,。。。] 或 [!it,it,。。。] 其中[!开头表示筛选方式为排除,it为单个索引或区间。 -* -* 区间格式为 start:end 或 start:end:step,其中start为0可省略,end为-1可省略。 -* -* 索引,区间两端及间隔都支持负数 -* -* 例如 tag.div[-1, 3:-2:-10, 2] -* -* 特殊用法 tag.div[-1:0] 可在任意地方让列表反向 -* -* */ - - ------------------- - 已测试过各种“&&”、“||”,“%%”切分的规则及两者索引写法,没发现大问题,坤飞大大可以再测试看看 +package io.legado.app.model.analyzeRule + +import androidx.annotation.Keep +import com.jayway.jsonpath.JsonPath +import com.jayway.jsonpath.ReadContext +import java.util.* + +@Suppress("RegExpRedundantEscape") +@Keep +class AnalyzeByJSonPath(json: Any) { + + companion object { + + fun parse(json: Any): ReadContext { + return when (json) { + is ReadContext -> json + is String -> JsonPath.parse(json) //JsonPath.parse(json) + else -> JsonPath.parse(json) //JsonPath.parse(json) + } + } + } + + private var ctx: ReadContext = parse(json) + + /** + * 改进解析方法 + * 解决阅读”&&“、”||“与jsonPath支持的”&&“、”||“之间的冲突 + * 解决{$.rule}形式规则可能匹配错误的问题,旧规则用正则解析内容含‘}’的json文本时,用规则中的字段去匹配这种内容时,会匹配错误.现改用平衡嵌套方法解决这个问题 + * */ + fun getString(rule: String): String? { + if (rule.isEmpty()) return null + var result: String + val ruleAnalyzes = RuleAnalyzer(rule) + val rules = ruleAnalyzes.splitRule("&&","||") + + if (rules.size == 1) { + + ruleAnalyzes.reSetPos() //将pos重置为0,复用解析器 + + result = ruleAnalyzes.innerRule("{$."){ getString(it) } //替换所有{$.rule...} + + if (result.isEmpty()) { //st为空,表明无成功替换的内嵌规则 + + try { + + val ob = ctx.read(rule) + + result =(if (ob is List<*>) { + + val builder = StringBuilder() + for (o in ob) { + builder.append(o).append("\n") + } + + builder.deleteCharAt(builder.lastIndex) //删除末尾赘余换行 + + builder + + } else ob).toString() + + } catch (ignored: Exception) { + } + + } + + return result + + } else { + val textList = arrayListOf() + for (rl in rules) { + val temp = getString(rl) + if (!temp.isNullOrEmpty()) { + textList.add(temp) + if (ruleAnalyzes.elementsType == "||") { + break + } + } + } + return textList.joinToString("\n") + } + } + + internal fun getStringList(rule: String): List { + val result = ArrayList() + if (rule.isEmpty()) return result + val ruleAnalyzes = RuleAnalyzer(rule) + val rules = ruleAnalyzes.splitRule("&&","||","%%") + + if (rules.size == 1) { + + ruleAnalyzes.reSetPos() //将pos重置为0,复用解析器 + + val st = ruleAnalyzes.innerRule("{$."){ getString(it) } //替换所有{$.rule...} + + if (st.isEmpty()) { //st为空,表明无成功替换的内嵌规则 + + try { + + val obj = ctx.read(rule) //kotlin的Any型返回值不包含null ,删除赘余 ?: return result + + if (obj is List<*>) { + + for (o in obj) result.add(o.toString()) + + } else result.add(obj.toString()) + + } catch (ignored: Exception) { + } + + }else result.add(st) + + return result + + } else { + val results = ArrayList>() + for (rl in rules) { + val temp = getStringList(rl) + if (temp.isNotEmpty()) { + results.add(temp) + if (temp.isNotEmpty() && ruleAnalyzes.elementsType == "||") { + break + } + } + } + if (results.size > 0) { + if ("%%" == ruleAnalyzes.elementsType) { + for (i in results[0].indices) { + for (temp in results) { + if (i < temp.size) { + result.add(temp[i]) + } + } + } + } else { + for (temp in results) { + result.addAll(temp) + } + } + } + return result + } + } + + internal fun getObject(rule: String): Any { + return ctx.read(rule) + } + + internal fun getList(rule: String): ArrayList? { + val result = ArrayList() + if (rule.isEmpty()) return result + val ruleAnalyzes = RuleAnalyzer(rule) + val rules = ruleAnalyzes.splitRule("&&","||","%%") + if (rules.size == 1) { + ctx.let { + try { + return it.read>(rules[0]) + } catch (e: Exception) { + e.printStackTrace() + } + } + return null + } else { + val results = ArrayList>() + for (rl in rules) { + val temp = getList(rl) + if (temp != null && temp.isNotEmpty()) { + results.add(temp) + if (temp.isNotEmpty() && ruleAnalyzes.elementsType == "||") { + break + } + } + } + if (results.size > 0) { + if ("%%" == ruleAnalyzes.elementsType) { + for (i in 0 until results[0].size) { + for (temp in results) { + if (i < temp.size) { + temp[i]?.let { result.add(it) } + } + } + } + } else { + for (temp in results) { + result.addAll(temp) + } + } + } + } + return result + } + +}