Разделить строку в Lua?
Мне нужно сделать простое разделение строки, но для этого, похоже, нет функции, и ручной способ, который я тестировал, похоже, не работал. Как бы я это сделал?
13 ответов:
см. Разбиение Строки:
вот различные способы разбиения a строка в список подстрок, разрыв исходной строки на вхождения некоторого разделителя (символ, набор символов, или узор.) Это обычно называется функция разделения строк[2].
вот мое простое решение. Используйте функцию gmatch для захвата строк, которые содержат по крайней мере один символ чего-либо, кроме нужного разделителя. По умолчанию разделителем является любой пробел (%s в Lua):
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, вы должны попробовать строку.gmatch() или String.суб() методы. Используйте строку.sub () метод, если вы знаете индекс, в котором вы хотите разделить строку, или использовать строку.gmatch () если вы будете анализировать строку, чтобы найти место для разделения строки.
пример использования string.gmatch () from Справочное Руководство Lua 5.1:
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.gmatch
найти шаблоны в строке эта функция найдет вещи между модели: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 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","\:")
Для большего идите сюда:
http://lua-users.org/wiki/SplitJoin
Мне нравится это короткое решение
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.
объяснение:
The
gmatch
функция работает как итератор, она извлекает все строки, которые соответствуютregex
. Элементregex
принимает все символы, пока не найдет сепаратора.
вы можете использовать этот метод:
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)
просто сидя на разделитель
local str = 'one,two' local regxEverythingExceptComma = '([^,]+)' for x in string.gmatch(str, regxEverythingExceptComma) do print(x) end
я использовал приведенные выше примеры, чтобы создать свою собственную функцию. Но недостающая часть для меня автоматически ускользала от волшебных персонажей.
вот мой вклад:
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
путь, не замеченный в других
function str_split(str, sep) if sep == nil then sep = '%s' end local res = {} local func = function(w) table.insert(res, w) end string.gsub(str, '[^'..sep..']+', func) return res end
многие из этих ответов принимают только односимвольные разделители или плохо справляются с краевыми случаями (например, пустые разделители), поэтому я подумал, что обеспечу более окончательное решение.
вот две функции,
gsplit
иsplit
, адаптированный код на расширение Scribunto MediaWiki, который используется на Вики, как Википедия. Код лицензируется под GPL v2. Я изменил имена переменных и добавил комментарии сделайте код немного проще для понимания, и я также изменил код, чтобы использовать обычные шаблоны строк Lua вместо шаблонов Scribunto для строк Unicode. Исходный код и тесты здесь.-- 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
функции В использовать: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', '')) -- f o o