pull/38/head
kunfei 5 years ago
parent 376f235f65
commit 38e3c77fd9
  1. 100
      app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeByRegex.kt
  2. 101
      app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt

@ -1,6 +1,5 @@
package io.legado.app.model.analyzeRule package io.legado.app.model.analyzeRule
import android.text.TextUtils
import java.util.* import java.util.*
import java.util.regex.Pattern import java.util.regex.Pattern
@ -57,103 +56,4 @@ object AnalyzeByRegex {
return getElements(result.toString(), regs, ++vIndex) return getElements(result.toString(), regs, ++vIndex)
} }
} }
// 拆分正则表达式替换规则(如:$\d{1,2}或${name}) /*注意:千万别用正则表达式拆分字符串,效率太低了!*/
fun splitRegexRule(str: String, ruleParam: MutableList<String>, ruleType: MutableList<Int>) {
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
}
} }

@ -306,22 +306,6 @@ class AnalyzeRule(private var book: BaseBook? = null) {
return vRuleStr 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 //分离put
rule = splitPutRule(rule, putMap) rule = splitPutRule(rule, putMap)
//get替换 //get,{{ }},$, 替换
rule = replaceGet(rule) var start = 0
// 拆分表达式替换规则 var tmp: String
if (mode != Mode.Js) { val evalMatcher = evalPattern.matcher(rule)
AnalyzeByRegex.splitRegexRule(rule, ruleParam, ruleType) 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 var j = ruleParam.size
while (j-- > 0) { while (j-- > 0) {
val regType = ruleType[j] val regType = ruleType[j]
if (regType > 0) { when {
@Suppress("UNCHECKED_CAST") regType > 0 -> {
val resultList = result as List<String?> @Suppress("UNCHECKED_CAST")
if (resultList.size > regType) { val resultList = result as List<String?>
resultList[regType]?.let { if (resultList.size > regType) {
infoVal.insert(0, resultList[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) { regType == -2 -> {
val jsEval: Any = evalJS(ruleParam[j], result) infoVal.insert(0, get(ruleParam[j]))
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 { else -> infoVal.insert(0, ruleParam[j])
infoVal.insert(0, ruleParam[j])
} }
} }
rule = infoVal.toString() rule = infoVal.toString()
@ -503,8 +522,8 @@ class AnalyzeRule(private var book: BaseBook? = null) {
return value return value
} }
operator fun get(key: String): String? { operator fun get(key: String): String {
return book?.variableMap?.get(key) return book?.variableMap?.get(key) ?: ""
} }
/** /**
@ -523,6 +542,10 @@ class AnalyzeRule(private var book: BaseBook? = null) {
companion object { companion object {
private val putPattern = Pattern.compile("@put:(\\{[^}]+?\\})", Pattern.CASE_INSENSITIVE) private val putPattern = Pattern.compile("@put:(\\{[^}]+?\\})", Pattern.CASE_INSENSITIVE)
private val getPattern = Pattern.compile("@get:\\{([^}]+?)\\}", 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
)
} }
/** /**

Loading…
Cancel
Save