Мне нужно сделать простое разделение строки, но для этого не существует функции, и ручной метод, который я тестировал, не работает. Как мне это сделать?Сплит-струна в Луа?
ответ
Пожалуйста см Splitting Strings:
Здесь находятся различные способы расщепления строку в список подстрок, нарушающих исходную строку на вхождений некоторого сепаратор (символы, набора символов или шаблона). Обычно это называется функцией разделения строк [2] .
Если вы разделили строку в Lua, вы должны попробовать методы string.gmatch() или string.sub(). Используйте метод string.sub(), если вам известен индекс, который вы хотите разбить на строку, или используйте string.gmatch(), если вы проанализируете строку, чтобы найти местоположение для разделения строки на.
Пример использования string.gmatch() из Lua 5.1 Reference Manual:
t = {}
s = "from=world, to=Lua"
for k, v in string.gmatch(s, "(%w+)=(%w+)") do
t[k] = v
end
Я «заимствовал» реализацию с этой страницы lua-users спасибо в любом случае – RCIX
Вот функция:
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
Подобно тому, как 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
По умолчанию это возвращает все, что разделено пробелами.
+1. Обратите внимание на других начинающих Lua: это возвращает итератор, а «между шаблонами» включает начало и конец строки. (Как новичок, я должен был попытаться понять это.) –
Если вы просто хотите перебрать лексемы, это довольно опрятно:
line = "one, two and 3!"
for token in string.gmatch(line, "[^%s]+") do
print(token)
end
Выход:
один,
два
и
3!
Краткое описание: шаблон «[^% s] +» соответствует каждой непустой строке между символами пробела.
Образец '% S' равен тому, который вы упомянули, так как'% S' является отрицанием '% s', например'% D' является отрицанием '% d'. Кроме того, '% w' равно' [A-Za-z0-9_] '(другие символы могут поддерживаться в зависимости от вашей локали). –
Вы можете использовать этот метод:
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)
Вот мой очень простое решение. Используйте функцию 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
Спасибо. ** Просто **, что я искал. – Nicholas
Вау, первый ответ во всем этом вопросе, который фактически имеет функцию, возвращающую таблицу. Обратите внимание, что мне нужен и «локальный» модификатор, так как это вы переписываете глобальные переменные. :) – cib
Это сработало. Это просто для одиночных разделителей символов. Чтобы разделить на строки, например теги XML, измените шаблон соответствия на «(.-) (« .. sep .. »)». Примечание. Если строка заканчивается на sep, последнее совпадение не будет выполнено. Чтобы исправить это, добавьте новую строку или любой символ в конец строки ввода. –
Мне нравится этот короткий Раствор
function split(s, delimiter)
result = {};
for match in (s..delimiter):gmatch("(.-)"..delimiter) do
table.insert(result, match);
end
return result;
end
Это мой любимый, так как он настолько короткий и просто. Я не совсем понимаю, что происходит, может кто-нибудь объяснить мне? – hexagonest
Это не удается при использовании точки в качестве разделителя (или, возможно, любого другого символа магии) – TurboHz
Потому что есть более чем один способ кожи кошки, вот мой подход:
Код:
#!/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
принимает все символы, пока не найдет разделитель.
Я использовал приведенные выше примеры для создания собственной функции. Но недостающая часть для меня автоматически ускользала от волшебных персонажей.
Вот мой вклад:
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
Многих из этих ответов смиритесь сепараторами односимвольных, или не иметь дело с крайними случаями хорошо (например, пустые разделители), поэтому я подумал, что дам более решительное решение.
Вот две функции, gsplit
и split
, адаптированные из code в Scribunto MediaWiki extension, который используется на вики как Википедия. Код лицензируется по лицензии GPL v2. Я изменил имена переменных и добавил комментарии, чтобы сделать код немного понятным, и я также изменил код, чтобы использовать обычные строковые шаблоны Lua вместо шаблонов Scribunto для строк Unicode. Исходный код имеет тестовые примеры here.
-- 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
К сожалению, страница была отредактирована с тех пор (хотя это на одной и той же теме), и прохождение цитируете не происходит на странице , Вот почему это идеальное решение, чтобы избежать ответов только на ссылки и фактически включать соответствующую информацию в сам ответ. – ShreevatsaR