我需要做一个简单的字符串分割,但似乎没有一个函数,我测试的手动方式似乎不起作用。我该怎么做呢?
当前回答
你可以使用这个方法:
function string:split(delimiter)
local result = { }
local from = 1
local delim_from, delim_to = string.find( self, delimiter, from )
while delim_from do
table.insert( result, string.sub( self, from , delim_from-1 ) )
from = delim_to + 1
delim_from, delim_to = string.find( self, delimiter, from )
end
table.insert( result, string.sub( self, from ) )
return result
end
delimiter = string.split(stringtodelimite,pattern)
其他回答
这个问题已经很晚了,但如果有人想要一个处理分裂数量的版本,你想要.....
-- Split a string into a table using a delimiter and a limit
string.split = function(str, pat, limit)
local t = {}
local fpat = "(.-)" .. pat
local last_end = 1
local s, e, cap = str:find(fpat, 1)
while s do
if s ~= 1 or cap ~= "" then
table.insert(t, cap)
end
last_end = e+1
s, e, cap = str:find(fpat, last_end)
if limit ~= nil and limit <= #t then
break
end
end
if last_end <= #str then
cap = str:sub(last_end)
table.insert(t, cap)
end
return t
end
我发现许多其他答案都有失败的边缘情况(例如。当给定的字符串包含#,{或}字符,或给定的分隔符,如%,需要转义)。下面是我使用的实现:
local function newsplit(delimiter, str)
assert(type(delimiter) == "string")
assert(#delimiter > 0, "Must provide non empty delimiter")
-- Add escape characters if delimiter requires it
delimiter = delimiter:gsub("[%(%)%.%%%+%-%*%?%[%]%^%$]", "%%%0")
local start_index = 1
local result = {}
while true do
local delimiter_index, _ = str:find(delimiter, start_index)
if delimiter_index == nil then
table.insert(result, str:sub(start_index))
break
end
table.insert(result, str:sub(start_index, delimiter_index - 1))
start_index = delimiter_index + 1
end
return result
end
如果你在Lua中拆分字符串,你应该尝试string.gmatch()或string.sub()方法。如果知道要分割字符串的索引,则使用string.sub()方法;如果要解析字符串以找到要分割字符串的位置,则使用string.gmatch()方法。
使用Lua 5.1参考手册中的string.gmatch()示例:
t = {}
s = "from=world, to=Lua"
for k, v in string.gmatch(s, "(%w+)=(%w+)") do
t[k] = v
end
如果你只想遍历这些令牌,这是非常简洁的:
line = "one, two and 3!"
for token in string.gmatch(line, "[^%s]+") do
print(token)
end
输出:
一个, 两个 而且 3!
简单解释:“[^%s]+”模式匹配空格字符之间的每个非空字符串。
对于那些从“在Lua中编程”这本书的练习10.1中学习过的人来说,似乎很清楚我们不能使用后面书中解释的概念(迭代器),而且函数应该接受多个字符分隔符。
split()是一个让模式匹配不需要的内容(split)并在空字符串上返回一个空表的技巧。plainSplit()的返回更像其他语言中的split。
magic = "([%%%.%(%)%+%*%?%[%]%^%$])"
function split(str, sep, plain)
if plain then sep = string.gsub(sep, magic, "%%%1") end
local N = '\255'
str = N..str..N
str = string.gsub(str, sep, N..N)
local result = {}
for word in string.gmatch(str, N.."(.-)"..N) do
if word ~= "" then
table.insert(result, word)
end
end
return result
end
function plainSplit(str, sep)
sep = string.gsub(sep, magic, "%%%1")
local result = {}
local start = 0
repeat
start = start + 1
local from, to = string.find(str, sep, start)
from = from and from-1
local word = string.sub(str, start, from, true)
table.insert(result, word)
start = to
until start == nil
return result
end
function tableToString(t)
local ret = "{"
for _, word in ipairs(t) do
ret = ret .. '"' .. word .. '", '
end
ret = string.sub(ret, 1, -3)
ret = ret .. "}"
return #ret > 1 and ret or "{}"
end
function runSplit(func, title, str, sep, plain)
print("\n" .. title)
print("str: '"..str.."'")
print("sep: '"..sep.."'")
local t = func(str, sep, plain)
print("-- t = " .. tableToString(t))
end
print("\n\n\n=== Pattern split ===")
runSplit(split, "Exercice 10.1", "a whole new world", " ")
runSplit(split, "With trailing seperator", " a whole new world ", " ")
runSplit(split, "A word seperator", "a whole new world", " whole ")
runSplit(split, "Pattern seperator", "a1whole2new3world", "%d")
runSplit(split, "Magic characters as plain seperator", "a$.%whole$.%new$.%world", "$.%", true)
runSplit(split, "Control seperator", "a\0whole\1new\2world", "%c")
runSplit(split, "ISO Time", "2020-07-10T15:00:00.000", "[T:%-%.]")
runSplit(split, " === [Fails] with \\255 ===", "a\255whole\0new\0world", "\0", true)
runSplit(split, "How does your function handle empty string?", "", " ")
print("\n\n\n=== Plain split ===")
runSplit(plainSplit, "Exercice 10.1", "a whole new world", " ")
runSplit(plainSplit, "With trailing seperator", " a whole new world ", " ")
runSplit(plainSplit, "A word seperator", "a whole new world", " whole ")
runSplit(plainSplit, "Magic characters as plain seperator", "a$.%whole$.%new$.%world", "$.%")
runSplit(plainSplit, "How does your function handle empty string?", "", " ")
输出
=== Pattern split ===
Exercice 10.1
str: 'a whole new world'
sep: ' '
-- t = {"a", "whole", "new", "world"}
With trailing seperator
str: ' a whole new world '
sep: ' '
-- t = {"a", "whole", "new", "world"}
A word seperator
str: 'a whole new world'
sep: ' whole '
-- t = {"a", "new world"}
Pattern seperator
str: 'a1whole2new3world'
sep: '%d'
-- t = {"a", "whole", "new", "world"}
Magic characters as plain seperator
str: 'a$.%whole$.%new$.%world'
sep: '$.%'
-- t = {"a", "whole", "new", "world"}
Control seperator
str: 'awholenewworld'
sep: '%c'
-- t = {"a", "whole", "new", "world"}
ISO Time
str: '2020-07-10T15:00:00.000'
sep: '[T:%-%.]'
-- t = {"2020", "07", "10", "15", "00", "00", "000"}
=== [Fails] with \255 ===
str: 'a�wholenewworld'
sep: ''
-- t = {"a"}
How does your function handle empty string?
str: ''
sep: ' '
-- t = {}
=== Plain split ===
Exercice 10.1
str: 'a whole new world'
sep: ' '
-- t = {"a", "whole", "new", "world"}
With trailing seperator
str: ' a whole new world '
sep: ' '
-- t = {"", "", "a", "", "whole", "", "", "new", "world", "", ""}
A word seperator
str: 'a whole new world'
sep: ' whole '
-- t = {"a", "new world"}
Magic characters as plain seperator
str: 'a$.%whole$.%new$.%world'
sep: '$.%'
-- t = {"a", "whole", "new", "world"}
How does your function handle empty string?
str: ''
sep: ' '
-- t = {""}
推荐文章
- Ruby数组到字符串的转换
- 为什么在Java和。net中不能修改字符串?
- 如何创建一个日期对象从字符串在javascript
- 在Android上将字符串转换为整数
- 删除字符串的最后3个字符
- 如何大写一个字符串的第一个字母在省道?
- 不区分大小写的列表排序,没有降低结果?
- indexOf()和search()的区别是什么?
- 我如何在Swift连接字符串?
- 如何获得一个变量值,如果变量名存储为字符串?
- 在Ruby中不创建新字符串而修饰字符串的规范方法是什么?
- 为什么不是字符串。空一个常数?
- 如何删除表中特定列的第一个字符?
- 我应该如何从字符串中删除所有的前导空格?- - - - - -斯威夫特
- 将整数转换为字符串,以逗号表示千