在Lua中分割string?
我需要做一个简单的string拆分,但似乎没有这个function,我testing的手动方式似乎没有工作。 我该怎么做?
请参阅分割string :
以下是将string拆分为子string列表的各种方法,在出现某些分隔符(字符,字符集或模式)时打破原始string。 这通常被称为string拆分[2]函数。
这是我真正简单的解决scheme。 使用gmatch函数来捕获至less包含除希望的分隔符之外的任何其他任何字符的string。 分隔符是默认情况下的任何空格(Lua中的%s):
function mysplit(inputstr, sep) if sep == nil then sep = "%s" end local t={} ; i=1 for str in string.gmatch(inputstr, "([^"..sep.."]+)") do t[i] = str i = i + 1 end return t end
如果要在Lua中分割一个string,则应该尝试使用string.gmatch()或string.sub()方法。 如果您知道要将string拆分的索引,请使用string.sub()方法,如果要parsingstring以查找拆分string的位置,请使用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] +”模式匹配空格字符之间的每个非空string。
就像string.gmatch
会在string中查找模式一样 ,这个函数会在模式之间find事物:
function string:split(pat) pat = pat or '%s+' local st, g = 1, self:gmatch("()("..pat..")") local function getter(segs, seps, sep, cap1, ...) st = sep and seps + #sep return self:sub(segs, (seps or 0) - 1), cap1 or sep, ... end return function() if st then return getter(st, g()) end end end
默认情况下,它返回由空格分隔的任何东西。
这是function:
function split(pString, pPattern) local Table = {} -- NOTE: use {n = 0} in Lua-5.0 local fpat = "(.-)" .. pPattern local last_end = 1 local s, e, cap = pString:find(fpat, 1) while s do if s ~= 1 or cap ~= "" then table.insert(Table,cap) end last_end = e+1 s, e, cap = pString:find(fpat, last_end) end if last_end <= #pString then cap = pString:sub(last_end) table.insert(Table, cap) end return Table end
像这样称呼它:
list=split(string_to_split,pattern_to_match)
例如:
list=split("1:2:3:4","\:")
我喜欢这个简短的解决scheme
function split(s, delimiter) result = {}; for match in (s..delimiter):gmatch("(.-)"..delimiter) do table.insert(result, match); end return result; end
因为有一种以上的方式去皮肤猫,这是我的方法:
代码 :
#!/usr/bin/env lua local content = [=[ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. ]=] local function split(str, sep) local result = {} local regex = ("([^%s]+)"):format(sep) for each in str:gmatch(regex) do table.insert(result, each) end return result end local lines = split(content, "\n") for _,line in ipairs(lines) do print(line) end
输出 : Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
说明 :
gmatch
函数作为一个迭代器,它提取所有匹配regex
的string。 regex
需要所有字符,直到find分隔符。
你可以使用这个方法:
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)
我用上面的例子来制作我自己的function。 但是对我而言,缺失的部分是自动逃离魔法angular色。
这是我的贡献:
function split(text, delim) -- returns an array of fields based on text and delimiter (one character only) local result = {} local magic = "().%+-*?[]^$" if delim == nil then delim = "%s" elseif string.find(delim, magic, 1, true) then -- escape magic delim = "%"..delim end local pattern = "[^"..delim.."]+" for w in string.gmatch(text, pattern) do table.insert(result, w) end return result end
简单地坐在分隔符上
local str = 'one,two' local regxEverythingExceptComma = '([^,]+)' for x in string.gmatch(str, regxEverythingExceptComma) do print(x) end
很多这些答案只接受单字符分隔符,或者没有很好地处理边缘情况(例如空分隔符),所以我想我会提供一个更确定的解决scheme。
这里有两个函数gsplit
和split
,它们是从Scribunto MediaWiki扩展中的代码改编而来的,这个扩展在Wikipedia上使用。 该代码根据GPL v2授权。 我已经更改了variables名称并添加了注释以使代码更容易理解,并且我还更改了代码,以使用常规的Luastring模式而不是Scribunto的Unicodestring模式。 原始代码在这里有testing用例。
-- gsplit: iterate over substrings in a string separated by a pattern -- -- Parameters: -- text (string) - the string to iterate over -- pattern (string) - the separator pattern -- plain (boolean) - if true (or truthy), pattern is interpreted as a plain -- string, not a Lua pattern -- -- Returns: iterator -- -- Usage: -- for substr in gsplit(text, pattern, plain) do -- doSomething(substr) -- end local function gsplit(text, pattern, plain) local splitStart, length = 1, #text return function () if splitStart then local sepStart, sepEnd = string.find(text, pattern, splitStart, plain) local ret if not sepStart then ret = string.sub(text, splitStart) splitStart = nil elseif sepEnd < sepStart then -- Empty separator! ret = string.sub(text, splitStart, sepStart) if sepStart < length then splitStart = sepStart + 1 else splitStart = nil end else ret = sepStart > splitStart and string.sub(text, splitStart, sepStart - 1) or '' splitStart = sepEnd + 1 end return ret end end end -- split: split a string into substrings separated by a pattern. -- -- Parameters: -- text (string) - the string to iterate over -- pattern (string) - the separator pattern -- plain (boolean) - if true (or truthy), pattern is interpreted as a plain -- string, not a Lua pattern -- -- Returns: table (a sequence table containing the substrings) local function split(text, pattern, plain) local ret = {} for match in gsplit(text, pattern, plain) do table.insert(ret, match) end return ret end
一些使用中的split
function的例子:
local function printSequence(t) print(unpack(t)) end printSequence(split('foo, bar,baz', ',%s*')) -- foo bar baz printSequence(split('foo, bar,baz', ',%s*', true)) -- foo, bar,baz printSequence(split('foo', '')) -- foo