lua 处理utf8 字符集(计算长度和截取子串,其他语言类似)

来源:互联网 发布:java软件编程培训价格 编辑:程序博客网 时间:2024/04/28 21:45

按字面个数来截取

函数(字符串, 开始位置, 截取长度)utf8sub("你好1世界哈哈",2,5)  =   好1世界哈utf8sub("1你好1世界哈哈",2,5) =   你好1世界utf8sub("你好世界1哈哈",1,5)  =   你好世界1utf8sub("12345678",3,5)     =   34567utf8sub("øpø你好pix",2,5)   =   pø你好p

错误方法

网上找了一些算法, 都不太正确; 要么就是乱码, 要么就是只考虑了4 byte 中文的情况, 不够全面

  1. string.sub(s,1,截取长度*4)

    网上很多直接使用"""string.sub(s,1,截取长度*4)"是肯定不对的, 因为如果中英文混合的字符串, 例如你好1世界的字符长度分别是4,4,1,4,4, 如果截取4个字, 4*4=4+4+1+4+3, 那世界字将会被取前3个byte, 就会出现乱码

  2. if byte>128 then index = index + 4

问题关键

  1. utf8字符是变长字符
  2. 字符长度有规律

UTF-8字符规律

字符串的首个byte表示了该utf8字符的长度

0xxxxxxx - 1 byte110yxxxx - 192, 2 byte1110yyyy - 225, 3 byte11110zzz - 240, 4 byte

各种正确算法

-- 判断utf8字符byte长度-- 0xxxxxxx - 1 byte-- 110yxxxx - 192, 2 byte-- 1110yyyy - 225, 3 byte-- 11110zzz - 240, 4 bytelocal function chsize(char)    if not char then        print("not char")        return 0    elseif char > 240 then        return 4    elseif char > 225 then        return 3    elseif char > 192 then        return 2    else        return 1    endend-- 计算utf8字符串字符数, 各种字符都按一个字符计算-- 例如utf8len("1你好") => 3function utf8len(str)    local len = 0    local currentIndex = 1    while currentIndex <= #str do        local char = string.byte(str, currentIndex)        currentIndex = currentIndex + chsize(char)        len = len +1    end    return lenend-- 截取utf8 字符串-- str:         要截取的字符串-- startChar:   开始字符下标,从1开始-- numChars:    要截取的字符长度function utf8sub(str, startChar, numChars)    local startIndex = 1    while startChar > 1 do        local char = string.byte(str, startIndex)        startIndex = startIndex + chsize(char)        startChar = startChar - 1    end    local currentIndex = startIndex    while numChars > 0 and currentIndex <= #str do        local char = string.byte(str, currentIndex)        currentIndex = currentIndex + chsize(char)        numChars = numChars -1    end    return str:sub(startIndex, currentIndex - 1)end-- 自测function test()    -- test utf8len    assert(utf8len("你好1世界哈哈") == 7)    assert(utf8len("你好世界1哈哈 ") == 8)    assert(utf8len(" 你好世 界1哈哈") == 9)    assert(utf8len("12345678") == 8)    assert(utf8len("øpø你好pix") == 8)    -- test utf8sub    assert(utf8sub("你好1世界哈哈",2,5) == "好1世界哈")    assert(utf8sub("1你好1世界哈哈",2,5) == "你好1世界")    assert(utf8sub(" 你好1世界 哈哈",2,6) == "你好1世界 ")    assert(utf8sub("你好世界1哈哈",1,5) == "你好世界1")    assert(utf8sub("12345678",3,5) == "34567")    assert(utf8sub("øpø你好pix",2,5) == "pø你好p")    print("all test succ")endtest()
0 0
原创粉丝点击