diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeByRegex.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeByRegex.kt index 7518aa57d..28e022fb5 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeByRegex.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeByRegex.kt @@ -1,6 +1,5 @@ package io.legado.app.model.analyzeRule -import android.text.TextUtils import java.util.* import java.util.regex.Pattern @@ -57,103 +56,4 @@ object AnalyzeByRegex { return getElements(result.toString(), regs, ++vIndex) } } - - // 拆分正则表达式替换规则(如:$\d{1,2}或${name}) /*注意:千万别用正则表达式拆分字符串,效率太低了!*/ - fun splitRegexRule(str: String, ruleParam: MutableList, ruleType: MutableList) { - if (TextUtils.isEmpty(str)) { - ruleParam.add("") - ruleType.add(0) - return - } - var index = 0 - var start = 0 - val len = str.length - while (index < len) { - if (str[index] == '$') { - if (index + 1 >= len) { - break - } else if (str[index + 1] == '{') { - if (index > start) { - ruleParam.add(str.substring(start, index)) - ruleType.add(0) - start = index - } - index += 2 - while (index < len) { - if (str[index] == '}') { - ruleParam.add(str.substring(start + 2, index)) - ruleType.add(-1) - start = ++index - break - } else if (str[index] == '$' || str[index] == '@') { - break - } - index++ - } - } else if (str[index + 1] in '0'..'9') { - if (index > start) { - ruleParam.add(str.substring(start, index)) - ruleType.add(0) - start = index - } - if (index + 2 < len && str[index + 2] >= '0' && str[index + 2] <= '9') { - ruleParam.add(str.substring(start, index + 3)) - ruleType.add(string2Int(ruleParam[ruleParam.size - 1])) - index += 3 - start = index - } else { - ruleParam.add(str.substring(start, index + 2)) - ruleType.add(string2Int(ruleParam[ruleParam.size - 1])) - index += 2 - start = index - } - } else { - index++ - } - } else if (str[index] == '{') { - if (index + 1 >= len) { - break - } else if (str[index + 1] == '{') { - if (index > start) { - ruleParam.add(str.substring(start, index)) - ruleType.add(0) - start = index - } - while (index + 1 < len) { - if (str[index] == '}' && str[index + 1] == '}') { - ruleParam.add(str.substring(start + 2, index)) - ruleType.add(-11) - start = index + 2 - break - } - index++ - } - } else { - index++ - } - } else { - index++ - } - } - if (index > start) { - ruleParam.add(str.substring(start, index)) - ruleType.add(0) - } - } - - // String数字转int数字的高效方法(利用ASCII值判断) - private fun string2Int(s: String): Int { - var r = 0 - var n: Char - var i = 0 - val l = s.length - while (i < l) { - n = s[i] - if (n in '0'..'9') { - r = r * 10 + (n.toInt() - 0x30) //'0-9'的ASCII值为0x30-0x39 - } - i++ - } - return r - } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt index 13dbfad04..71d22bc3e 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt @@ -306,22 +306,6 @@ class AnalyzeRule(private var book: BaseBook? = null) { return vRuleStr } - /** - * 替换@get - */ - private fun replaceGet(ruleStr: String): String { - var vRuleStr = ruleStr - val getMatcher = getPattern.matcher(vRuleStr) - while (getMatcher.find()) { - var value = "" - book?.variableMap?.get(getMatcher.group(1))?.let { - value = it - } - vRuleStr = vRuleStr.replace(getMatcher.group(), value) - } - return vRuleStr - } - /** * 正则替换 */ @@ -454,11 +438,41 @@ class AnalyzeRule(private var book: BaseBook? = null) { } //分离put rule = splitPutRule(rule, putMap) - //get替换 - rule = replaceGet(rule) - // 拆分表达式替换规则 - if (mode != Mode.Js) { - AnalyzeByRegex.splitRegexRule(rule, ruleParam, ruleType) + //get,{{ }},$, 替换 + var start = 0 + var tmp: String + val evalMatcher = evalPattern.matcher(rule) + while (evalMatcher.find()) { + if (evalMatcher.start() > start) { + tmp = rule.substring(start, evalMatcher.start()) + ruleType.add(0) + ruleParam.add(tmp) + } + tmp = evalMatcher.group() + when { + tmp.startsWith("$") -> { + ruleType.add(tmp.substring(1).toInt()) + ruleParam.add(tmp) + } + tmp.startsWith("@get:", true) -> { + ruleType.add(-2) + ruleParam.add(tmp.substring(6, tmp.lastIndex)) + } + tmp.startsWith("{{") -> { + ruleType.add(-1) + ruleParam.add(tmp.substring(2, tmp.length - 2)) + } + else -> { + ruleType.add(0) + ruleParam.add(tmp) + } + } + start = evalMatcher.end() + } + if (rule.length > start) { + tmp = rule.substring(start) + ruleType.add(0) + ruleParam.add(tmp) } } @@ -468,25 +482,30 @@ class AnalyzeRule(private var book: BaseBook? = null) { var j = ruleParam.size while (j-- > 0) { val regType = ruleType[j] - if (regType > 0) { - @Suppress("UNCHECKED_CAST") - val resultList = result as List - if (resultList.size > regType) { - resultList[regType]?.let { - infoVal.insert(0, resultList[regType]) + when { + regType > 0 -> { + @Suppress("UNCHECKED_CAST") + val resultList = result as List + if (resultList.size > regType) { + resultList[regType]?.let { + infoVal.insert(0, resultList[regType]) + } + } + } + regType == -1 -> { + val jsEval: Any = evalJS(ruleParam[j], result) + if (jsEval is String) { + infoVal.insert(0, jsEval) + } else if (jsEval is Double && jsEval % 1.0 == 0.0) { + infoVal.insert(0, String.format("%.0f", jsEval)) + } else { + infoVal.insert(0, jsEval.toString()) } } - } else if (regType < 0) { - val jsEval: Any = evalJS(ruleParam[j], result) - if (jsEval is String) { - infoVal.insert(0, jsEval) - } else if (jsEval is Double && jsEval % 1.0 == 0.0) { - infoVal.insert(0, String.format("%.0f", jsEval)) - } else { - infoVal.insert(0, jsEval.toString()) + regType == -2 -> { + infoVal.insert(0, get(ruleParam[j])) } - } else { - infoVal.insert(0, ruleParam[j]) + else -> infoVal.insert(0, ruleParam[j]) } } rule = infoVal.toString() @@ -503,8 +522,8 @@ class AnalyzeRule(private var book: BaseBook? = null) { return value } - operator fun get(key: String): String? { - return book?.variableMap?.get(key) + operator fun get(key: String): String { + return book?.variableMap?.get(key) ?: "" } /** @@ -523,6 +542,10 @@ class AnalyzeRule(private var book: BaseBook? = null) { companion object { private val putPattern = Pattern.compile("@put:(\\{[^}]+?\\})", Pattern.CASE_INSENSITIVE) private val getPattern = Pattern.compile("@get:\\{([^}]+?)\\}", Pattern.CASE_INSENSITIVE) + private val evalPattern = Pattern.compile( + "@get:\\{[^}]+?\\}|\\{\\{[\\w\\W]*?\\}\\}|\\$\\d{1,2}", + Pattern.CASE_INSENSITIVE + ) } /**