字符串子无法正常工作
String sub not working correctly
我还有一个关于 lua 的问题。我创建了一种方法来计算某些价格的总额。价格采用这种格式:500 英镑。因此,为了将它们转换为数字,我使用了 string:sub() 和 tonumber(),但我得到了一些奇怪的结果。这是我的代码:`
function functions.calculateTotalAmount()
print("calculating total amount")
saveData.totalAmount = 0
print("There are " .. #saveData.amounts .. " in the amount file")
for i=1, #saveData.names do
print("SaveData.amounts[" .. i .. "] original = " .. saveData.amounts[i])
print("SaveData.amounts[" .. i .. "] after sub= " .. saveData.amounts[i]:sub(2))
print("totalAmount: " .. saveData.totalAmount)
if saveData.income[i] then
saveData.totalAmount = saveData.totalAmount + tonumber(saveData.amounts[i]:sub(2))
else
saveData.totalAmount = saveData.totalAmount - tonumber(saveData.amounts[i]:sub(2))
end
end
totalAmountStr.text = saveData.totalAmount .. " " .. currencyFull
loadsave.saveTable(saveData, "payMeBackTable.json")
结束
我在 for 循环中打印了一些信息以确定问题,这是 for 循环中前 2 个打印语句打印的内容:
16:03:51.452 SaveData.amounts1原=¥201
16:03:51.452 SaveData.amounts1 在 sub= 201
之后
它在 Whosebug 中看起来不错,但 ¥ 实际上并没有在我的日志中消失,而是被一个奇怪的矩形符号代替。此 post 将附有打印文本的图片。
有人看到这里发生了什么吗?
string.sub()
作用于字符串的 字节 ,而不作用于它的 个字符 。当字符串包含 Unicode 文本时会有所不同。
如果数字在字符串的末尾,用
提取它
amount = tonumber(saveData.amounts[i]:match("%d+$"))
在这种情况下不要使用 sub
,因为 ¥
符号可能是一个多字节序列(取决于编码),因此使用 sub(2)
就是在切割它在中间而不是删除它。
改为使用 gsub("[^%d%.]+","")
删除所有非数字部分。
Lua 字符串是 字节 的字符串,而不是 字符 的字符串。 ASCII 字符长度为 1 个字节,但大多数其他字符占用多个字节,因此使用 string.sub()
是行不通的。
字节和字符(或代码点)之间的转换有多种标准,但到目前为止,网络上最常见的是 UTF-8。如果您使用的是 Lua 5.3 或更高版本,则可以使用新的 built-in functions 来执行 UTF-8 操作。例如,要获取 UTF-8 字符串的子字符串,您可以这样做:
-- Simple version without bounds-checking.
function utf8_sub1(s, start_char_idx, end_char_idx)
start_byte_idx = utf8.offset(s, start_char_idx)
end_byte_idx = utf8.offset(s, end_char_idx + 1) - 1
return string.sub(s, start_byte_idx, end_byte_idx)
end
-- More robust version with bounds-checking.
function utf8_sub2(s, start_char_idx, end_char_idx)
start_byte_idx = utf8.offset(s, start_char_idx)
end_byte_idx = utf8.offset(s, end_char_idx + 1)
if start_byte_idx == nil then
start_byte_idx = 1
end
if end_byte_idx == nil then
end_byte_idx = -1
else
end_byte_idx = end_byte_idx - 1
end
return string.sub(s, start_byte_idx, end_byte_idx)
end
s = "¥201"
print(string.sub(s, 2, 4)) -- an invalid byte sequence
print(utf8_sub1(s, 2, 4)) -- "201"
print(utf8_sub2(s, 2, 4)) -- "201"
print(utf8_sub1(s, 2, 5)) -- throws an error
如果您没有 Lua 5.3,您可以使用像 this one 这样的 UTF-8 库来实现相同的功能。
我还有一个关于 lua 的问题。我创建了一种方法来计算某些价格的总额。价格采用这种格式:500 英镑。因此,为了将它们转换为数字,我使用了 string:sub() 和 tonumber(),但我得到了一些奇怪的结果。这是我的代码:`
function functions.calculateTotalAmount()
print("calculating total amount")
saveData.totalAmount = 0
print("There are " .. #saveData.amounts .. " in the amount file")
for i=1, #saveData.names do
print("SaveData.amounts[" .. i .. "] original = " .. saveData.amounts[i])
print("SaveData.amounts[" .. i .. "] after sub= " .. saveData.amounts[i]:sub(2))
print("totalAmount: " .. saveData.totalAmount)
if saveData.income[i] then
saveData.totalAmount = saveData.totalAmount + tonumber(saveData.amounts[i]:sub(2))
else
saveData.totalAmount = saveData.totalAmount - tonumber(saveData.amounts[i]:sub(2))
end
end
totalAmountStr.text = saveData.totalAmount .. " " .. currencyFull
loadsave.saveTable(saveData, "payMeBackTable.json")
结束
我在 for 循环中打印了一些信息以确定问题,这是 for 循环中前 2 个打印语句打印的内容:
16:03:51.452 SaveData.amounts1原=¥201
16:03:51.452 SaveData.amounts1 在 sub= 201
之后它在 Whosebug 中看起来不错,但 ¥ 实际上并没有在我的日志中消失,而是被一个奇怪的矩形符号代替。此 post 将附有打印文本的图片。
有人看到这里发生了什么吗?
string.sub()
作用于字符串的 字节 ,而不作用于它的 个字符 。当字符串包含 Unicode 文本时会有所不同。
如果数字在字符串的末尾,用
提取它amount = tonumber(saveData.amounts[i]:match("%d+$"))
在这种情况下不要使用 sub
,因为 ¥
符号可能是一个多字节序列(取决于编码),因此使用 sub(2)
就是在切割它在中间而不是删除它。
改为使用 gsub("[^%d%.]+","")
删除所有非数字部分。
Lua 字符串是 字节 的字符串,而不是 字符 的字符串。 ASCII 字符长度为 1 个字节,但大多数其他字符占用多个字节,因此使用 string.sub()
是行不通的。
字节和字符(或代码点)之间的转换有多种标准,但到目前为止,网络上最常见的是 UTF-8。如果您使用的是 Lua 5.3 或更高版本,则可以使用新的 built-in functions 来执行 UTF-8 操作。例如,要获取 UTF-8 字符串的子字符串,您可以这样做:
-- Simple version without bounds-checking.
function utf8_sub1(s, start_char_idx, end_char_idx)
start_byte_idx = utf8.offset(s, start_char_idx)
end_byte_idx = utf8.offset(s, end_char_idx + 1) - 1
return string.sub(s, start_byte_idx, end_byte_idx)
end
-- More robust version with bounds-checking.
function utf8_sub2(s, start_char_idx, end_char_idx)
start_byte_idx = utf8.offset(s, start_char_idx)
end_byte_idx = utf8.offset(s, end_char_idx + 1)
if start_byte_idx == nil then
start_byte_idx = 1
end
if end_byte_idx == nil then
end_byte_idx = -1
else
end_byte_idx = end_byte_idx - 1
end
return string.sub(s, start_byte_idx, end_byte_idx)
end
s = "¥201"
print(string.sub(s, 2, 4)) -- an invalid byte sequence
print(utf8_sub1(s, 2, 4)) -- "201"
print(utf8_sub2(s, 2, 4)) -- "201"
print(utf8_sub1(s, 2, 5)) -- throws an error
如果您没有 Lua 5.3,您可以使用像 this one 这样的 UTF-8 库来实现相同的功能。