Мне нужно сделать простое разбиение строки, но, похоже, для этого не существует функции, а ручной метод, который я тестировал, не сработал. Как бы я это сделал?
Вот мое действительно простое решение. Используйте функцию gmatch для захвата строк, которые содержат хотя бы один символ чего-либо, кроме требуемого разделителя. Разделителем является ** любой * пробел (% s в Lua) по умолчанию:
function mysplit (inputstr, sep)if sep ==nilthen
sep ="%s"endlocal t={}for str in string.gmatch(inputstr,"([^"..sep.."]+)")do
table.insert(t, str)endreturn t
end
Вау, первый ответ во всем этом вопросе, который на самом деле имеет функцию, которая возвращает таблицу. Обратите внимание, что t и мне нужен модификатор "local", так как вы перезаписываете глобальные переменные. :)
Cib
3
Как уже отмечали другие, вы можете упростить это, используя table.insert (t, str) вместо t [i] = str, и тогда вам не нужно i = 1 или i = i +1
Джеймс Ньютон,
2
Не работает, если строка содержит пустые значения, например. 'foo,,bar', Вы получаете {'foo','bar'}вместо{'foo', '', 'bar'}
Андрас
5
Это правильно. Следующая версия будет работать в этом случае: function split(inputstr, sep) sep=sep or '%s' local t={} for field,s in string.gmatch(inputstr, "([^"..sep.."]*)("..sep.."?)") do table.insert(t,field) if s=="" then return t end end end
Bart
33
Если вы разбиваете строку в Lua, вам следует попробовать методы string.gmatch () или string.sub (). Используйте метод string.sub (), если вам известен индекс, по которому вы хотите разделить строку, или используйте string.gmatch (), если вы проанализируете строку, чтобы найти место для разделения строки.
Образец %Sравен тому, который вы упомянули, как %Sи отрицание %s, как %Dи отрицание %d. Кроме того, %wравно [A-Za-z0-9_](другие символы могут поддерживаться в зависимости от вашей локали).
Ларс Гируп Бринк Нильсен
14
Так же, как string.gmatchбудет искать шаблоны в строке, эта функция найдет вещи между шаблонами:
function string:split(pat)
pat = pat or'%s+'local st, g =1, self:gmatch("()("..pat..")")localfunction getter(segs, seps, sep, cap1,...)
st = sep and seps +#sep
return self:sub(segs,(seps or0)-1), cap1 or sep,...endreturnfunction()if st thenreturn getter(st, g())endendend
По умолчанию он возвращает все, что разделено пробелами.
+1. Примечание для любых других начинающих Lua: это возвращает итератор, а «между шаблонами» включает начало и конец строки. (Как новичку я должен был попытаться это выяснить.)
Дарий Бэкон
12
Вот функция:
function split(pString, pPattern)local Table ={}-- NOTE: use {n = 0} in Lua-5.0local fpat ="(.-)".. pPattern
local last_end =1local s, e, cap = pString:find(fpat,1)while s doif s ~=1or cap ~=""then
table.insert(Table,cap)end
last_end = e+1
s, e, cap = pString:find(fpat, last_end)endif last_end <=#pString then
cap = pString:sub(last_end)
table.insert(Table, cap)endreturn Table
end
Это мой любимый, потому что он такой короткий и простой. Я не совсем понимаю, что происходит, кто-то может мне объяснить?
hexagonest
2
Это не удается при использовании точки в качестве разделителя (или, возможно, любого другого магического персонажа)
TurboHz
6
Поскольку существует более одного способа снятия шкуры с кошки, вот мой подход:
Код :
#!/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.
]=]localfunction split(str, sep)local result ={}local regex =("([^%s]+)"):format(sep)for each in str:gmatch(regex)do
table.insert(result, each)endreturn result
endlocal 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принимает все символы, пока не найдет разделитель.
function string:split(delimiter)local result ={}local from =1local 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)
Многие из этих ответов принимают только односимвольные разделители или плохо разбираются в крайних случаях (например, пустые разделители), поэтому я подумал, что смогу найти более определенное решение.
Вот две функции, 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)-- endlocalfunction gsplit(text, pattern, plain)local splitStart, length =1,#text
returnfunction()if splitStart thenlocal sepStart, sepEnd = string.find(text, pattern, splitStart, plain)local ret
ifnot sepStart then
ret = string.sub(text, splitStart)
splitStart =nilelseif sepEnd < sepStart then-- Empty separator!
ret = string.sub(text, splitStart, sepStart)if sepStart < length then
splitStart = sepStart +1else
splitStart =nilendelse
ret = sepStart > splitStart and string.sub(text, splitStart, sepStart -1)or''
splitStart = sepEnd +1endreturn ret
endendend-- 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)localfunction split(text, pattern, plain)local ret ={}for match in gsplit(text, pattern, plain)do
table.insert(ret, match)endreturn ret
end
Некоторые примеры использования splitфункции:
localfunction 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
function str_split(str, sep)if sep ==nilthen
sep ='%s'endlocal res ={}local func =function(w)
table.insert(res, w)end
string.gsub(str,'[^'..sep..']+', func)return res
end
Я использовал приведенные выше примеры для создания своей собственной функции. Но пропавшая часть для меня автоматически убегала от магических персонажей.
Вот мой вклад:
function split(text, delim)-- returns an array of fields based on text and delimiter (one character only)local result ={}local magic ="().%+-*?[]^$"if delim ==nilthen
delim ="%s"elseif string.find(delim, magic,1,true)then-- escape magic
delim ="%"..delim
endlocal pattern ="[^"..delim.."]+"for w in string.gmatch(text, pattern)do
table.insert(result, w)endreturn result
end
Супер поздно на этот вопрос, но в случае, если кто-то хочет версию, которая обрабатывает количество расколов, которые вы хотите получить .....
-- 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 =1local s, e, cap = str:find(fpat,1)while s doif s ~=1or cap ~=""then
table.insert(t, cap)end
last_end = e+1
s, e, cap = str:find(fpat, last_end)if limit ~=niland limit <=#t thenbreakendendif last_end <=#str then
cap = str:sub(last_end)
table.insert(t, cap)endreturn t
end
Если вы программируете на Lua, вам здесь не повезло. Lua - это единственный язык программирования, который просто печально известен своей печально известной репутацией, потому что его авторы никогда не реализовывали функцию «разделения» в стандартной библиотеке, а вместо этого написали 16 скриншотов с объяснениями и неубедительными оправданиями того, почему они этого не сделали и не будут вкраплен многочисленными полуработающими примерами, которые практически гарантированно сработают почти для всех, но не сработают в вашем угловом деле. Это просто уровень Lua, и каждый, кто программирует на Lua, просто сжимает зубы и перебирает персонажей. Существует множество решений, которые иногда лучше, но ровно нулевых решений, которые надежно лучше.
Ответы:
Вот мое действительно простое решение. Используйте функцию gmatch для захвата строк, которые содержат хотя бы один символ чего-либо, кроме требуемого разделителя. Разделителем является ** любой * пробел (% s в Lua) по умолчанию:
,
источник
'foo,,bar'
, Вы получаете{'foo','bar'}
вместо{'foo', '', 'bar'}
function split(inputstr, sep) sep=sep or '%s' local t={} for field,s in string.gmatch(inputstr, "([^"..sep.."]*)("..sep.."?)") do table.insert(t,field) if s=="" then return t end end end
Если вы разбиваете строку в Lua, вам следует попробовать методы string.gmatch () или string.sub (). Используйте метод string.sub (), если вам известен индекс, по которому вы хотите разделить строку, или используйте string.gmatch (), если вы проанализируете строку, чтобы найти место для разделения строки.
Пример использования string.gmatch () из справочного руководства Lua 5.1 :
источник
Если вы просто хотите перебрать токены, это довольно аккуратно:
Вывод:
Краткое объяснение: шаблон «[^% s] +» соответствует каждой непустой строке между пробелами.
источник
%S
равен тому, который вы упомянули, как%S
и отрицание%s
, как%D
и отрицание%d
. Кроме того,%w
равно[A-Za-z0-9_]
(другие символы могут поддерживаться в зависимости от вашей локали).Так же, как
string.gmatch
будет искать шаблоны в строке, эта функция найдет вещи между шаблонами:По умолчанию он возвращает все, что разделено пробелами.
источник
Вот функция:
Назовите это как:
например:
Для получения дополнительной информации перейдите сюда:
http://lua-users.org/wiki/SplitJoin
источник
Мне нравится это короткое решение
источник
Поскольку существует более одного способа снятия шкуры с кошки, вот мой подход:
Код :
Выход :
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
принимает все символы, пока не найдет разделитель.источник
Вы можете использовать этот метод:
источник
Многие из этих ответов принимают только односимвольные разделители или плохо разбираются в крайних случаях (например, пустые разделители), поэтому я подумал, что смогу найти более определенное решение.
Вот две функции,
gsplit
иsplit
, адаптированная из кода в расширении Scribunto MediaWiki , который используется на вики как Википедия. Код распространяется по лицензии GPL v2 . Я изменил имена переменных и добавил комментарии, чтобы немного облегчить понимание кода, а также изменил код, чтобы использовать обычные строковые шаблоны Lua вместо шаблонов Scribunto для строк Unicode. Оригинальный код имеет тестовые случаи здесь .Некоторые примеры использования
split
функции:источник
путь не виден в других
источник
Просто сидим на разделителе
источник
Я использовал приведенные выше примеры для создания своей собственной функции. Но пропавшая часть для меня автоматически убегала от магических персонажей.
Вот мой вклад:
источник
Вы можете использовать библиотеку Penlight . У этого есть функция для разделения строки, используя разделитель, который выводит список.
В нем реализованы многие функции, которые могут нам понадобиться при программировании и отсутствовать в Lua.
Вот пример для его использования.
источник
В зависимости от варианта использования это может быть полезно. Он обрезает весь текст по обе стороны от флагов:
Вывод:
источник
Супер поздно на этот вопрос, но в случае, если кто-то хочет версию, которая обрабатывает количество расколов, которые вы хотите получить .....
источник
Если вы программируете на Lua, вам здесь не повезло. Lua - это единственный язык программирования, который просто печально известен своей печально известной репутацией, потому что его авторы никогда не реализовывали функцию «разделения» в стандартной библиотеке, а вместо этого написали 16 скриншотов с объяснениями и неубедительными оправданиями того, почему они этого не сделали и не будут вкраплен многочисленными полуработающими примерами, которые практически гарантированно сработают почти для всех, но не сработают в вашем угловом деле. Это просто уровень Lua, и каждый, кто программирует на Lua, просто сжимает зубы и перебирает персонажей. Существует множество решений, которые иногда лучше, но ровно нулевых решений, которые надежно лучше.
источник