函数参照c#的StringBuilder
1 require "utf8Ext" 2 3 StringBuilder = StringBuilder or {} 4 5 function StringBuilder.new() 6 local inst = {} 7 8 local charBuff = {} 9 local len = 0 10 11 function inst:count() 12 return len 13 end 14 15 function inst:get(index) 16 assert(index >= 1 and index <= len, "get: out of range") 17 return charBuff[index] 18 end 19 20 function inst:clear() 21 for i=1,len do 22 charBuff[i] = nil 23 end 24 len = 0 25 return self 26 end 27 28 --function inst:capacity() end 29 30 function inst:copyTo(dst) 31 error("todo") 32 end 33 34 function inst:append(value, index, count) 35 local vType = type(value) 36 if "string" == vType then 37 local tb, ct = string.utf8CharArray(value, index, count, charBuff, len+1) 38 len = len + ct 39 elseif "number" == vType then 40 local str = tostring(value) 41 local strLen = #str 42 for i=1,strLen do 43 charBuff[len+i] = str:sub(i, i) 44 end 45 len = len + strLen 46 else 47 error("append: invalid value type: " .. vType) 48 end 49 return self 50 end 51 52 function inst:insert(index, value, vIndex, count) 53 assert(index >= 1 and index <= len, "insert: out of range") 54 55 local vType = type(value) 56 if "string" == vType then 57 if nil == count then count = string.utf8StringLen(value) end 58 59 for i=len,index,-1 do --往后移n个 60 charBuff[i+count] = charBuff[i] 61 end 62 string.utf8CharArray(value, vIndex, count, charBuff, index) 63 len = len + count 64 elseif "number" == vType then 65 for i=len,index,-1 do --往后移1个 66 charBuff[i+1] = charBuff[i] 67 end 68 charBuff[index] = value 69 len = len + 1 70 else 71 error("insert: invalid value type: " .. vType) 72 end 73 return self 74 end 75 76 function inst:replace(oldValue, newValue, index, count) 77 error("todo") 78 --[[ 79 local vType = type(value) 80 if "string" == vType then 81 else 82 error("replace: invalid value type: " .. vType) 83 end 84 return self 85 ]] 86 end 87 88 function inst:remove(index, count) 89 assert(index >= 1 and index <= len, "remove: out of range") 90 local index2 = index + count 91 92 if index2 > len then --删除尾部的n个元素 93 for i=index,len do 94 charBuff[i] = nil 95 end 96 len = index - 1 97 else --删除中间或开头的n个元素 98 local j = index 99 for i=index2,len do --尾部的元素往前填充 100 charBuff[j] =charBuff[i] 101 j = j + 1 102 end 103 for i=j,len do 104 charBuff[i] = nil 105 end 106 len = len - count 107 end 108 return self 109 end 110 111 function inst:__tostring() 112 if 0 == len then return "" end 113 return table.concat(charBuff) 114 end 115 116 function inst:__len() 117 return len 118 end 119 120 function inst:__index(k) 121 assert("number" == type(k), "k not number: " .. k) 122 return self:get(k) 123 end 124 125 function inst:__newindex(k, v) 126 assert("number" == type(k), "k not number: " .. k) 127 assert("string" == type(v) and 1 == string.utf8StringLen(v), "v not utf8 char: " .. v .. ":" .. type(v)) 128 charBuff[k] = v 129 end 130 131 setmetatable(inst, inst) 132 return inst 133 end 134 135 function StringBuilder.__call() 136 return StringBuilder.new() 137 end 138 setmetatable(StringBuilder, StringBuilder)
测试代码:
1 local function Test1() 2 local sb = StringBuilder() 3 assert(0 == sb:count(), "count error") 4 5 sb:append("中文") 6 assert(2 == sb:count(), "append error") 7 assert("中" == sb[1], "append error") 8 assert("文" == sb[2], "append error") 9 assert("中文" == tostring(sb)) 10 11 sb:append(12) 12 assert(4 == sb:count(), "append error") 13 assert("中" == sb[1], "append error") 14 assert("文" == sb[2], "append error") 15 assert("1" == sb[3], "append error") 16 assert("2" == sb[4], "append error") 17 assert("中文12" == tostring(sb)) 18 19 sb[4] = "3" 20 assert(4 == sb:count(), "append error") 21 assert("中" == sb[1], "append error") 22 assert("文" == sb[2], "append error") 23 assert("1" == sb[3], "append error") 24 assert("3" == sb[4], "append error") 25 assert("中文13" == tostring(sb)) 26 27 --sb[4] = 3 --error 28 --sb[4] = "aa" 29 sb:insert(1, "汉语") 30 assert(6 == sb:count(), "insert error") 31 assert("汉语中文13" == tostring(sb)) 32 33 sb:insert(5, 00) 34 assert("汉语中文013" == tostring(sb)) 35 36 sb:insert(3, "。,!") 37 assert(10 == sb:count(), "insert error") 38 assert("汉语。,!中文013" == tostring(sb)) 39 40 sb:remove(2, 4) 41 assert(6 == sb:count(), "remove error") 42 assert("汉中文013" == tostring(sb)) 43 44 sb:remove(5, 2) 45 assert(4 == sb:count(), "remove error") 46 assert("汉中文0" == tostring(sb)) 47 48 sb:remove(4, 10) 49 assert(3 == sb:count(), "remove error") 50 assert("汉中文" == tostring(sb)) 51 52 sb:remove(1, 2) 53 assert(1 == sb:count(), "remove error") 54 assert("文" == tostring(sb)) 55 end 56 57 Test1()