Вопрос:
Мне нужно сделать простое разделение строки, но для этого не существует функции, и ручной метод, который я тестировал, не работает. Как мне это сделать?
Лучший ответ:
См. Разделение строк:
Здесь представлены различные способы разделения string в список подстрок, разбиение исходной строки на вхождения некоторого разделителя (символ, набор символов или шаблон). Это обычно называют string split [2].
Ответ №1
Вот мое действительно простое решение. Используйте функцию gmatch для захвата строк, которые содержат как минимум один символ из чего-либо, кроме требуемого разделителя. Разделителем является ** любой * пробел (% s в Lua) по умолчанию:
function mysplit (inputstr, sep) if sep == nil then sep = «%s» end local t={} for str in string.gmatch(inputstr, «([^»..sep..»]+)») do table.insert(t, str) end return t end
.
Ответ №2
Если вы разделяете строку в Lua, вы должны попробовать методы string.gmatch() или string.sub(). Используйте метод string.sub(), если вам известен индекс, который вы хотите разбить на строку, или используйте string.gmatch(), если вы проанализируете строку, чтобы найти местоположение для разбиения строки на.
Пример использования string.gmatch() из Справочное руководство Lua 5.1:
t = {} s = «from=world, to=Lua» for k, v in string.gmatch(s, «(%w+)=(%w+)») do t[k] = v end Ответ №3
Если вы просто хотите перебрать маркеры, это довольно аккуратно:
line = «one, two and 3!» for token in string.gmatch(line, «[^%s]+») do print(token) end
Вывод:
один,
два
и
3
Краткое объяснение: шаблон “[^% s] +” соответствует каждой непустой строке между символами пробела.
Ответ №4
Так же, как 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
По умолчанию он возвращает все, что разделяется пробелами.
Ответ №5
Вот функция:
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
Ответ №6
Мне нравится это короткое решение
function split(s, delimiter) result = {}; for match in (s..delimiter):gmatch(«(.-)»..delimiter) do table.insert(result, match); end return result; end Ответ №7
Потому что есть несколько способов кошки кошки, здесь мой подход:
Код
#!/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.
Объяснение:
Функция gmatch работает как итератор, она извлекает все строки, которые соответствуют regex. regex принимает все символы, пока не найдет разделитель.
Ответ №8
Вы можете использовать этот метод:
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) Ответ №9
Просто сидит на разделителе
local str = ‘one,two’ local regxEverythingExceptComma = ‘([^,]+)’ for x in string.gmatch(str, regxEverythingExceptComma) do print(x) end Ответ №10
Многие из этих ответов допускают только односимвольные разделители или не имеют дело с красными случаями (например, пустыми разделителями), поэтому я решил, что предоставил бы более окончательное решение.
Вот две функции: gsplit и split, адаптированные из code в Расширение 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 Ответ №11
путь не виден в других
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 Ответ №12
Я использовал приведенные выше примеры для создания собственной функции. Но недостающая часть для меня автоматически ускользала от волшебных персонажей.
Вот мой вклад:
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 Ответ №13
Вы можете использовать библиотеку Penlight. У этого есть функция для разделения строки, используя разделитель, который выводит список.
В нем реализованы многие функции, которые могут нам понадобиться при программировании и отсутствовать в Lua.
Вот пример для его использования.
> > stringx = require «pl.stringx» > > str = «welcome to the world of lua» > > arr = stringx.split(str, » «) > > arr {welcome,to,the,world,of,lua} > Ответ №14
В зависимости от варианта использования это может быть полезно. Он обрезает весь текст по обе стороны от флагов:
b = «This is a string used for testing» —Removes unwanted text c = (b:match(«a([^/]+)used»)) print (c)
Выход:
string