|
|
@ -5,28 +5,17 @@ package io.legado.app.model.analyzeRule |
|
|
|
class RuleAnalyzer(data: String, code: Boolean = false) { |
|
|
|
class RuleAnalyzer(data: String, code: Boolean = false) { |
|
|
|
|
|
|
|
|
|
|
|
private var queue: String = data //被处理字符串 |
|
|
|
private var queue: String = data //被处理字符串 |
|
|
|
private var pos = 0 //处理到的位置 |
|
|
|
private var pos = 0 //当前处理到的位置 |
|
|
|
private var rule = arrayOf<String>() |
|
|
|
private var start = 0 //当前处理字段的开始 |
|
|
|
|
|
|
|
private var startX = 0 //当前规则的开始 |
|
|
|
|
|
|
|
|
|
|
|
private var start = 0 //每次处理字段的开始 |
|
|
|
private var rule = arrayOf<String>() //分割出的规则列表 |
|
|
|
private var startX = 0 //规则的开始 |
|
|
|
|
|
|
|
private var innerStr: Boolean = false //true表示以平衡组的起点为规则起始,false表示不这样 |
|
|
|
|
|
|
|
private var step: Int = 0 //分割字符的长度 |
|
|
|
private var step: Int = 0 //分割字符的长度 |
|
|
|
|
|
|
|
var elementsType = "" //当前分割字符串 |
|
|
|
|
|
|
|
|
|
|
|
//设置平衡组函数,json或JavaScript时设置成chompCodeBalanced,否则为chompRuleBalanced |
|
|
|
//设置平衡组函数,json或JavaScript时设置成chompCodeBalanced,否则为chompRuleBalanced |
|
|
|
val chompBalanced = if (code) ::chompCodeBalanced else ::chompRuleBalanced |
|
|
|
val chompBalanced = if (code) ::chompCodeBalanced else ::chompRuleBalanced |
|
|
|
|
|
|
|
|
|
|
|
var elementsType = "" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//当前平衡字段 |
|
|
|
|
|
|
|
fun currBalancedString( |
|
|
|
|
|
|
|
stepStart: Int = 1, |
|
|
|
|
|
|
|
stepEnd: Int = 1 |
|
|
|
|
|
|
|
): String { //stepStart平衡字符的起始分隔字串长度,stepEnd平衡字符的结束分隔字串长度 |
|
|
|
|
|
|
|
return queue.substring(startX + stepStart, pos - stepEnd) //当前平衡字段 |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fun trim() { // 修剪当前规则之前的"@"或者空白符 |
|
|
|
fun trim() { // 修剪当前规则之前的"@"或者空白符 |
|
|
|
while (queue[pos] == '@' || queue[pos] < '!') pos++ |
|
|
|
while (queue[pos] == '@' || queue[pos] < '!') pos++ |
|
|
|
} |
|
|
|
} |
|
|
@ -41,13 +30,6 @@ class RuleAnalyzer(data: String, code: Boolean = false) { |
|
|
|
return queue.substring(start, pos) //当前拉取到的字段 |
|
|
|
return queue.substring(start, pos) //当前拉取到的字段 |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//剩余字串 |
|
|
|
|
|
|
|
private fun remainingString(): String { |
|
|
|
|
|
|
|
start = pos |
|
|
|
|
|
|
|
pos = queue.length |
|
|
|
|
|
|
|
return queue.substring(start) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* 是否已无剩余字符? |
|
|
|
* 是否已无剩余字符? |
|
|
|
* @return 若剩余字串中已无字符则返回true |
|
|
|
* @return 若剩余字串中已无字符则返回true |
|
|
@ -77,15 +59,13 @@ class RuleAnalyzer(data: String, code: Boolean = false) { |
|
|
|
* @param seq 分隔字符 **区分大小写** |
|
|
|
* @param seq 分隔字符 **区分大小写** |
|
|
|
* @return 是否找到相应字段。 |
|
|
|
* @return 是否找到相应字段。 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
fun consumeTo(seq: String, setStartPos: Boolean = true): Boolean { |
|
|
|
fun consumeTo(seq: String): Boolean { |
|
|
|
|
|
|
|
start = pos //将处理到的位置设置为规则起点 |
|
|
|
if (setStartPos) start = pos //将处理到的位置设置为规则起点 |
|
|
|
|
|
|
|
val offset = queue.indexOf(seq, pos) |
|
|
|
val offset = queue.indexOf(seq, pos) |
|
|
|
return if (offset != -1) { |
|
|
|
return if (offset != -1) { |
|
|
|
pos = offset |
|
|
|
pos = offset |
|
|
|
true |
|
|
|
true |
|
|
|
} else false |
|
|
|
} else false |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
@ -203,7 +183,7 @@ class RuleAnalyzer(data: String, code: Boolean = false) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* 拉出一个代码平衡组,存在转义文本,没有实体字符,通常以{}作为模块 |
|
|
|
* 拉出一个非内嵌代码平衡组,存在转义文本 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
fun chompCodeBalanced(open: Char, close: Char): Boolean { |
|
|
|
fun chompCodeBalanced(open: Char, close: Char): Boolean { |
|
|
|
|
|
|
|
|
|
|
@ -237,7 +217,6 @@ class RuleAnalyzer(data: String, code: Boolean = false) { |
|
|
|
} while (depth > 0 || otherDepth > 0) //拉出一个平衡字串 |
|
|
|
} while (depth > 0 || otherDepth > 0) //拉出一个平衡字串 |
|
|
|
|
|
|
|
|
|
|
|
return if (depth > 0 || otherDepth > 0) false else { |
|
|
|
return if (depth > 0 || otherDepth > 0) false else { |
|
|
|
if (innerStr) startX = this.pos //内嵌规则起始 |
|
|
|
|
|
|
|
this.pos = pos //同步位置 |
|
|
|
this.pos = pos //同步位置 |
|
|
|
true |
|
|
|
true |
|
|
|
} |
|
|
|
} |
|
|
@ -421,7 +400,6 @@ class RuleAnalyzer(data: String, code: Boolean = false) { |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* 替换内嵌规则 |
|
|
|
* 替换内嵌规则 |
|
|
|
* @param inner 起始标志,如{$. 或 {{ |
|
|
|
* @param inner 起始标志,如{$. 或 {{ |
|
|
@ -437,32 +415,23 @@ class RuleAnalyzer(data: String, code: Boolean = false) { |
|
|
|
fr: (String) -> String? |
|
|
|
fr: (String) -> String? |
|
|
|
): String { |
|
|
|
): String { |
|
|
|
|
|
|
|
|
|
|
|
val start0 = pos //规则匹配前起点 |
|
|
|
startX = pos //设置规则起点 |
|
|
|
|
|
|
|
|
|
|
|
innerStr = true //设置平衡组以平衡组起点为规则起始点 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val st = StringBuilder() |
|
|
|
val st = StringBuilder() |
|
|
|
|
|
|
|
|
|
|
|
while (!isEmpty && consumeTo(inner)) { //拉取成功返回true,ruleAnalyzes里的字符序列索引变量pos后移相应位置,否则返回false,且isEmpty为true |
|
|
|
while (consumeTo(inner)) { //拉取成功返回true,ruleAnalyzes里的字符序列索引变量pos后移相应位置,否则返回false,且isEmpty为true |
|
|
|
val posPre = pos //记录上次结束位置 |
|
|
|
if (chompCodeBalanced('{', '}')) { |
|
|
|
if (chompBalanced('{', '}')) { |
|
|
|
val frv = fr(queue.substring(start + startStep, pos - endStep)) |
|
|
|
val frv = fr(currBalancedString(startStep, endStep)) |
|
|
|
|
|
|
|
if (frv != null) { |
|
|
|
if (frv != null) { |
|
|
|
st.append(queue.substring(start, posPre) + frv) //压入内嵌规则前的内容,及内嵌规则解析得到的字符串 |
|
|
|
st.append(queue.substring(startX, start) + frv) //压入内嵌规则前的内容,及内嵌规则解析得到的字符串 |
|
|
|
|
|
|
|
startX = pos //记录下次规则起点 |
|
|
|
continue //获取内容成功,继续选择下个内嵌规则 |
|
|
|
continue //获取内容成功,继续选择下个内嵌规则 |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pos += inner.length //拉出字段不平衡,inner只是个普通字串,跳到此inner后继续匹配 |
|
|
|
pos += inner.length //拉出字段不平衡,inner只是个普通字串,跳到此inner后继续匹配 |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//匹配前起点与当前规则起点相同,证明无替换成功的内嵌规则,返回空字符串。否则返回替换后的字符串 |
|
|
|
st.append(queue.substring(startX)) //压入剩余字符串 |
|
|
|
return if (start0 == start) "" else { |
|
|
|
return st.toString() |
|
|
|
st.append(remainingString()) //压入剩余字符串 |
|
|
|
|
|
|
|
st.toString() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
companion object { |
|
|
|
companion object { |
|
|
|