Update RuleAnalyzer.kt

优化
pull/1111/head
bushixuanqi 3 years ago committed by GitHub
parent 4230cca24b
commit d567e217bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 99
      app/src/main/java/io/legado/app/model/analyzeRule/RuleAnalyzer.kt

@ -5,25 +5,23 @@ 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( fun currBalancedString(
stepStart: Int = 1, stepStart: Int = 1,
stepEnd: Int = 1 stepEnd: Int = 1
): String { //stepStart平衡字符的起始分隔字串长度,stepEnd平衡字符的结束分隔字串长度 ): String { //stepStart平衡字符的起始分隔字串长度,stepEnd平衡字符的结束分隔字串长度
return queue.substring(startX + stepStart, pos - stepEnd) //当前平衡字段 return queue.substring(start + stepStart, pos - stepEnd) //当前平衡字段
} }
@ -41,13 +39,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 +68,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
} }
/** /**
@ -135,13 +124,13 @@ class RuleAnalyzer(data: String, code: Boolean = false) {
//其中js只要符合语法,就不用避开任何阅读关键字,自由发挥 //其中js只要符合语法,就不用避开任何阅读关键字,自由发挥
fun chompJsBalanced( fun chompJsBalanced(
f: ((Char) -> Boolean?) = { f: ((Char) -> Boolean?) = {
when (it) { when (it) {
'{' -> true //开始嵌套一层 '{' -> true //开始嵌套一层
'}' -> false //闭合一层嵌套 '}' -> false //闭合一层嵌套
else -> null else -> null
}
} }
}
): Boolean { ): Boolean {
var pos = pos //声明变量记录临时处理位置 var pos = pos //声明变量记录临时处理位置
var depth = 0 //嵌套深度 var depth = 0 //嵌套深度
@ -159,11 +148,11 @@ class RuleAnalyzer(data: String, code: Boolean = false) {
var c = queue[pos++] var c = queue[pos++]
if (c != '\\') { //非转义字符 if (c != '\\') { //非转义字符
if (c == '\'' && !commits && !commit && !regex && !inDoubleQuote && !inOtherQuote) inSingleQuote = if (c == '\'' && !commits && !commit && !regex && !inDoubleQuote && !inOtherQuote) inSingleQuote =
!inSingleQuote //匹配具有语法功能的单引号 !inSingleQuote //匹配具有语法功能的单引号
else if (c == '"' && !commits && !commit && !regex && !inSingleQuote && !inOtherQuote) inDoubleQuote = else if (c == '"' && !commits && !commit && !regex && !inSingleQuote && !inOtherQuote) inDoubleQuote =
!inDoubleQuote //匹配具有语法功能的双引号 !inDoubleQuote //匹配具有语法功能的双引号
else if (c == '`' && !commits && !commit && !regex && !inSingleQuote && !inDoubleQuote) inOtherQuote = else if (c == '`' && !commits && !commit && !regex && !inSingleQuote && !inDoubleQuote) inOtherQuote =
!inOtherQuote //匹配具有语法功能的'`' !inOtherQuote //匹配具有语法功能的'`'
else if (c == '/' && !commits && !commit && !regex && !inSingleQuote && !inDoubleQuote && !inOtherQuote) { //匹配注释或正则起点 else if (c == '/' && !commits && !commit && !regex && !inSingleQuote && !inDoubleQuote && !inOtherQuote) { //匹配注释或正则起点
c = queue[pos++] c = queue[pos++]
when (c) { when (c) {
@ -203,7 +192,7 @@ class RuleAnalyzer(data: String, code: Boolean = false) {
} }
/** /**
* 拉出一个代码平衡组存在转义文本没有实体字符通常以{}作为模块 * 拉出一个非内嵌代码平衡组存在转义文本
*/ */
fun chompCodeBalanced(open: Char, close: Char): Boolean { fun chompCodeBalanced(open: Char, close: Char): Boolean {
@ -237,7 +226,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
} }
@ -344,10 +332,10 @@ class RuleAnalyzer(data: String, code: Boolean = false) {
val next = if (queue[pos] == '[') ']' else ')' //平衡组末尾字符 val next = if (queue[pos] == '[') ']' else ')' //平衡组末尾字符
if (!chompBalanced(queue[pos], next)) throw Error( if (!chompBalanced(queue[pos], next)) throw Error(
queue.substring( queue.substring(
0, 0,
start start
) + "后未平衡" ) + "后未平衡"
) //拉出一个筛选器,不平衡则报错 ) //拉出一个筛选器,不平衡则报错
} while (end > pos) } while (end > pos)
@ -404,10 +392,10 @@ class RuleAnalyzer(data: String, code: Boolean = false) {
val next = if (queue[pos] == '[') ']' else ')' //平衡组末尾字符 val next = if (queue[pos] == '[') ']' else ')' //平衡组末尾字符
if (!chompBalanced(queue[pos], next)) throw Error( if (!chompBalanced(queue[pos], next)) throw Error(
queue.substring( queue.substring(
0, 0,
start start
) + "后未平衡" ) + "后未平衡"
) //拉出一个筛选器,不平衡则报错 ) //拉出一个筛选器,不平衡则报错
} while (end > pos) } while (end > pos)
@ -421,7 +409,6 @@ class RuleAnalyzer(data: String, code: Boolean = false) {
} }
/** /**
* 替换内嵌规则 * 替换内嵌规则
* @param inner 起始标志,{$. {{ * @param inner 起始标志,{$. {{
@ -431,36 +418,32 @@ class RuleAnalyzer(data: String, code: Boolean = false) {
* *
* */ * */
fun innerRule( fun innerRule(
inner: String, inner: String,
startStep: Int = 1, startStep: Int = 1,
endStep: Int = 1, endStep: Int = 1,
fr: (String) -> String? fr: (String) -> String?
): String { ): String {
val start0 = pos //规则匹配前起点 val startXS = 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(currBalancedString(startStep, 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后继续匹配
} }
//匹配前起点与当前规则起点相同,证明无替换成功的内嵌规则,返回空字符串。否则返回替换后的字符串 //最初起点与当前规则起点相同,证明无替换成功的内嵌规则,返回空字符串。否则返回替换后的字符串
return if (start0 == start) "" else { return if (startX == startXS) "" else {
st.append(remainingString()) //压入剩余字符串 st.append(queue.substring(pos)) //压入剩余字符串
st.toString() st.toString()
} }
} }

Loading…
Cancel
Save