Lua元方法(Metamethod)

方法名 含义
__index 这是 metatable 最常用的键。当你通过键来访问 table 的时候,如果这个键没有值,那么Lua就会寻找该table的metatable(假定有metatable)中的index 键。如果index包含一个表格,Lua会在表格中查找相应的键
__newindex newindex 元方法用来对表更新。当你给表的一个缺少的索引赋值,解释器就会查找 newindex 元方法:如果存在则调用这个函数而不进行赋值操作。
__add + 操作。 如果任何不是数字的值(包括不能转换为数字的字符串)做加法, Lua 就会尝试调用元方法。 首先、Lua 检查第一个操作数(即使它是合法的), 如果这个操作数没有为 "__add" 事件定义元方法, Lua 就会接着检查第二个操作数。 一旦 Lua 找到了元方法, 它将把两个操作数作为参数传入元方法, 元方法的结果(调整为单个值)作为这个操作的结果。 如果找不到元方法,将抛出一个错误。
__sub - 操作。 行为和 "add" 操作类似。
__mul * 操作。 行为和 "add" 操作类似。
__div / 操作。 行为和 "add" 操作类似。
__mod % 操作。 行为和 "add" 操作类似。
__pow ^ (次方)操作。 行为和 "add" 操作类似。
__unm - (取负)操作。 行为和 "add" 操作类似。
__idiv // (向下取整除法)操作。 行为和 "add" 操作类似。
__band & (按位与)操作。 行为和 "add" 操作类似, 不同的是 Lua 会在任何一个操作数无法转换为整数时 (参见 §3.4.3)尝试取元方法。
__bor (按位或)操作。 行为和 "band" 操作类似。
__bxor ~ (按位异或)操作。 行为和 "band" 操作类似。
__bnot ~ (按位非)操作。 行为和 "band" 操作类似。
__shl << (左移)操作。 行为和 "band" 操作类似。
__shr >> (右移)操作。 行为和 "band" 操作类似。
__concat .. (连接)操作。 行为和 "add" 操作类似, 不同的是 Lua 在任何操作数即不是一个字符串 也不是数字(数字总能转换为对应的字符串)的情况下尝试元方法。
__len # (取长度)操作。 如果对象不是字符串,Lua 会尝试它的元方法。 如果有元方法,则调用它并将对象以参数形式传入, 而返回值(被调整为单个)则作为结果。 如果对象是一张表且没有元方法, Lua 使用表的取长度操作(参见 §3.4.7)。 其它情况,均抛出错误。
__eq == (等于)操作。 和 "add" 操作行为类似, 不同的是 Lua 仅在两个值都是表或都是完全用户数据 且它们不是同一个对象时才尝试元方法。 调用的结果总会被转换为布尔量。
__lt < (小于)操作。 和 "add" 操作行为类似, 不同的是 Lua 仅在两个值不全为整数也不全为字符串时才尝试元方法。 调用的结果总会被转换为布尔量。
__le <= (小于等于)操作。 和其它操作不同, 小于等于操作可能用到两个不同的事件。 首先,像 "lt" 操作的行为那样,Lua 在两个操作数中查找 "le" 元方法。 如果一个元方法都找不到,就会再次查找 "lt" 事件, 它会假设 a <= b 等价于 not (b < a)。 而其它比较操作符类似,其结果会被转换为布尔量。
__index 索引 table[key]。 当 table 不是表或是表 table 中不存在 key 这个键时,这个事件被触发。 此时,会读出 table 相应的元方法。

正则中的保留字

字符 含义
\ 做为转意,即通常在"\"后面的字符不按原来意义解释,如/b/匹配字符"b",当b前面加了反斜杆后/\b/,转意为匹配一个单词的边界。
-或- 对正则表达式功能字符的还原,如""匹配它前面元字符0次或多次,/a/将匹配a,aa,aaa,加了"\"后,/a*/将只匹配"a*"。
^ 匹配一个输入或一行的开头,/^a/匹配"an A",而不匹配"An a"
$ 匹配一个输入或一行的结尾,/a$/匹配"An a",而不匹配"an A"
* 匹配前面元字符0次或多次,/ba*/将匹配b,ba,baa,baaa
+ 匹配前面元字符1次或多次,/ba*/将匹配ba,baa,baaa
? 匹配前面元字符0次或1次,/ba*/将匹配b,ba
(x) 匹配x保存x在名为$1...$9的变量中
x|y 匹配x或y
{n} 精确匹配n次
{n,} 匹配n次以上
{n,m} 匹配n-m次
[xyz] 字符集(character set),匹配这个集合中的任一一个字符(或元字符)
[^xyz] 不匹配这个集合中的任何一个字符
[\b] 匹配一个退格符
\b 匹配一个单词的边界
\B 匹配一个单词的非边界
\cX 这儿,X是一个控制符,/\cM/匹配Ctrl-M
\d 匹配一个字数字符,/\d/ = /[0-9]/
\D 匹配一个非字数字符,/\D/ = /[^0-9]/
\n 匹配一个换行符
\r 匹配一个回车符
\s 匹配一个空白字符,包括\n,\r,\f,\t,\v等
\S 匹配一个非空白字符,等于/[^\n\f\r\t\v]/
\t 匹配一个制表符
\v 匹配一个重直制表符
\w 匹配一个可以组成单词的字符(alphanumeric,这是我的意译,含数字),包括下划线,如[\w]匹配"$5.98"中的5,等于[a-zA-Z0-9]
\W 匹配一个不可以组成单词的字符,如[\W]匹配"$5.98"中的$,等于[^a-zA-Z0-9]。

斜方向分割二维数组(lua简易实现)

分析规律(下图为11行-5列示例)

  • 同颜色数字相差值为列数-1
  • 可以产生(行数+列数-1)组数字(如图是15)
  • 每组数字中,每一行最多只有一个(同行号应舍去)

function formatVal(val)
    if val < 10 then return " " .. tostring(val) end
    return tostring(val)
end

local cols = 5
local rows = 11
local t = {}
local gap = " "
for r = 1, rows do
    local line = ""
    for c = 1, cols do
        local val = (r - 1) * cols + c
        table.insert(t, val, val)
        line = line .. " " .. formatVal(val)
    end
    print(line)
end

function SplitBySlash(t, cols, rows)
    local arr2 = {}
    local offset = cols - 1
    for c = 1, rows + cols - 1 do
        local arr = {}
        for r = 1, rows do
            local n = c + (r - 1) * offset
            local fakeR = math.ceil(n / cols)
            if fakeR == r then
                table.insert(arr, n)
                print(n, r, fakeR)
            end

        end
        print("================")
        table.insert(arr2, arr)
    end
    return arr2
end

local function __dump(var, level)
    local rval = {}
    table.insert(rval, "{")
    for k, v in pairs(var) do
        if type(v) == "table" and getmetatable(var) ~= v then
            if k ~= "__base" then
                table.insert(rval, string.format("%s%s=%s",
                                                 string.rep("    ", level), k,
                                                 __dump(v, level + 1)))
            end
        elseif type(v) ~= "function" then
            table.insert(rval, string.format("%s%s=%s",
                                             string.rep("    ", level), k,
                                             tostring(v)))
        end
    end
    table.insert(rval, string.format("%s}", string.rep("    ", level - 1)))
    return table.concat(rval, "\n")
end

local function log(inst)
    if inst == nil then
        print(nil)
        return
    end
    print(__dump(inst, 1))
end

local array2 = SplitBySlash(t, cols, rows)
log(array2)

最终效果

C# 使用LINQ比较两个数组的差异

string[] arrRate = new string[] { "a", "b", "c", "d" };//A
string[] arrTemp = new string[] { "c", "d", "e" };//B

string[] arrUpd = arrRate.Intersect(arrTemp).ToArray();//相同的数据 (结果:c,d)
string[] arrAdd = arrRate.Except(arrTemp).ToArray();//A中有B中没有的 (结果:a,b)
string[] arrNew = arrTemp.Except(arrRate).ToArray();//B中有A中没有的 (结果:e)

关于bash:在sed命令中转义正斜杠

  1. 如果replace内容不包含/这种写法没问题sed"s/regex/replace/" file
  2. 如果replace内容包含/,则改变分割符号为|,完整写法为 sed"s|regex|replace|" file ,这样就不用为\写转义了