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
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<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
}
/**
* 替换@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<String?>
if (resultList.size > regType) {
resultList[regType]?.let {
infoVal.insert(0, resultList[regType])
when {
regType > 0 -> {
@Suppress("UNCHECKED_CAST")
val resultList = result as List<String?>
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
)
}
/**

Loading…
Cancel
Save