======================================================================
这是一个快速可以完成批量替换任务(可二进制,可文本)的工具。
./rule/ts.rule
文件,是一个用于utf8文件的繁简替换脚本。内容行如:
//T--S
"丟","丢"
"並","并"
"亂","乱"
...
"龔","龚"
"龕","龛"
"龜","龟"
其中第一行为注释,用“//”开头 第二行以及以下,都是替换关系(当前只支持完全匹配,并不支持范围、正则等方式);
比如 "丟","丢"
会从输入序列中,与 "丟" 对应的utf8序列,'\xe4\xb8\x9f' 相匹配
的序列,将被替换为 '\xe4\xb8\xa2',也就是 "丢"。
替换关系的语法很简单,就是
map-rule: -> to-match ',' to-replace
to-match: -> c-style-string
to-replace: -> c-style-string
其中的 c-style-string ,也就是C风格的字符串,以"
开头和结尾;同时内部允许使用转
义字符;
支持的转义如下:
\00 - \77
\000 - \255
\x00 - \xFF
以及
\0
\\
\a
\b
\f
\n
\r
\t
\v
\'
\"
为了保证大量的替换规则,能够同时起作用,内部使用了“状态机”算法,以保证这一点。
本替换工具,本质上是一个状态机;内部状态机的生成,是通过读取规则文件,而动态生成 的。
每读入一条规则的时候,规则 to-match 部分,会按字节进行拆解。然后生成这条规则,所 对应的状态跳转表。而拆分出来的字节,就对应着状态跳转条件;最后一个状态,则附加一 个动作;该动作就是把 to-replace 字符串,在这个状态下打印出来;之后,状态机又会自 动变到初始状态,以便进行下一次跳转(匹配);
另外,为了达到“替换”文件的目的,对于不会发生跳转的输入(S0 -> S0),状态机会原 样输出。
-
byte-stream-editor pre-defined-rule-name file-to-replace [file-to-replace-n ...]
byte-stream-editor 工具,将会在app它所在的 ./rule 路径下,搜索 pre-defined-rule-name 或者 pre-defined-rule-name.rule 文件,当做规则文件进行 解析;
然后挨个对 file-to-replace 文件进行替换处理;
-
byte-stream-editor ./rule-file-name file-to-replace [file-to-replace-n ...]
byte-stream-editor 工具,当前工作目录,搜索 pre-defined-rule-name 或者 pre-defined-rule-name.rule 文件,当做规则文件进行解析;
然后挨个对 file-to-replace 文件进行替换处理;
-
byte-stream-editor /path/to/rule-file-name file-to-replace [file-to-replace-n ...]
byte-stream-editor 工具,由于提供的是绝对路径,此时该路径文件,当做规则文件进行解析;
然后挨个对 file-to-replace 文件进行替换处理;
另外,还有一种命令行方式:
byte-stream-editor -r <file-to-replace1 [file-to-replace-n ...]>
即,额外提供了 -r 参数;这个参数,是用来控制,是否覆盖被处理文件的。如果没有
这个参数,会在目标文件原位置,生成一个附带 .ts
后缀的同名文件;
如上所述,通过状态机;
工具在处理规则文件的时候,会将所有规则都用来生成从 S0 状态开始的状态跳转表。会在 逻辑上,生成一颗没有回路的,以S0为根节点的状态跳转树——同时,每一个叶子,都对应 着,每一个规则的 to-match 字符串,最后一个字节后,所跳转到的状态,并在其上,绑定 一个输出动作;
该动作完成后,重新从叶子,跳转到根S0;
在处理外部文件的替换的时候,就是应用该跳转树的时候。
每次处理一个新文件,状态都是从 S0 开始;然后循环,从外部文件中读取每一个字节,再 依次交给状态机;然后,状态机,会根据跳转条件(当前状态——跳转前位置;输入字符— —跳转条件),决定下一个状态;
如果规则中有对应的跳转方式记录,就会发生对应的跳转,同时将当前输入的字符,放入一 个临时的FIFO队列中——如果,该跳转后的状态,恰好是叶子状态,那么会将执行该状态绑 定的动作,并将得到的字符串,输出到外部流中,同时清空FIFO队列,并将状态跳至S0;
如果不满足规则,则状态回到S0,并把该FIFO队列中的字符,输出到输出流中,并清空该 FIFO队列,最后输出刚刚读入的字符;