4

我需要获取文本变量的第一个字符。我通过以下简单方法之一实现了这一点:

string.sub(someText,1,1)

或者

someText:sub(1,1)

如果我执行以下操作,我希望得到'ñ'第一个字母。但是,这两种sub方法的结果都是'Ã'

local someText = 'ñññññññ'
print('Test whole: '..someText) 
print('first char: '..someText:sub(1,1))
print('first char with .sub: '..string.sub(someText,1,1))

以下是控制台的结果:

2014-03-02 09:08:47.959 Corona Simulator[1701:507] Test whole: ñññññññ
2014-03-02 09:08:47.960 Corona Simulator[1701:507] first char: Ã
2014-03-02 09:08:47.960 Corona Simulator[1701:507] first char with .sub: Ã

似乎该string.sub()函数正在以 UTF-8 编码返回的值。只是为了好玩,我尝试使用utf8_decode()Corona SDK 提供的功能。它没有成功。模拟器表明该函数需要一个数字,但却得到了nil

我还搜索了网络,看看是否有其他人遇到过这个问题。我发现有很多关于 Lua、Corona、Unicode 和 UTF-8 的讨论,但我没有遇到任何可以解决这个特定问题的东西。

4

2 回答 2

4

Lua 字符串是 8 位干净的,这意味着 Lua 中的字符串是字节流。UTF-8 字符ñ有多个字节,但someText:sub(1,1)只返回第一个单字节。

对于 UTF-8 编码,ASCII范围内的所有字符都具有与 ASCII 相同的表示,即小于 128 的单个字节。对于其他 CodePoints,第一个字节在 194-244 范围内的字节序列和连续字节在 128-191 范围内。

因此,您可以使用该模式".[\128-\191]*"来匹配单个 UTF-8 CodePoint(不是 Grapheme):

for c in "ñññññññ":gmatch(".[\128-\191]*") do -- pretend the first string is in NFC
    print(c)
end

输出:

ñ
ñ
ñ
ñ
ñ
ñ
ñ
于 2014-03-02T15:41:31.543 回答
0

关于使用的字符集:只要知道您在自己的代码中加入了哪些要求,并确保这些要求确实得到满足。有各种典型要求:

  • ASCII 兼容(又名任何字节 < 128 表示 ASCII 字符,所有 ASCII 字符都表示为它们自己)
  • 固定大小与可变宽度(可能是自同步)字符集
  • 没有嵌入的 0 字节

编写代码,以便尽可能少地需要这些要求,并记录下来。

匹配单个 UTF-8 字符:确定 UTF-8 字符是什么意思。它是字形还是代码点?AFAIK 你需要完整的 unicode 表来进行字形匹配。你真的必须达到这个水平吗?

于 2014-03-02T18:29:21.677 回答