Відповіді:
Ось моє дійсно просте рішення. Використовуйте функцію 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
.
'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 :
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] +" відповідає кожному непустому рядку між символами пробілу.
%S
дорівнює тій, яку ви згадали, як %S
і заперечення %s
, як %D
і заперечення %d
. Крім того, %w
дорівнює [A-Za-z0-9_]
(інші символи можуть підтримуватися залежно від вашої мови).
Так само, як 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.
Пояснення :
У 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)
Багато з цих відповідей приймають лише розділові символи або не справляються з кращими справами (наприклад, порожні роздільники), тому я подумав, що запропоную більш чітке рішення.
Ось дві функції, gsplit
іsplit
, адаптовані з коду в розширенні Scribunto MediaWiki , який використовується на вікі, як Wikipedia. Код ліцензований відповідно до 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
Просто сидіти на роздільнику
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
Ви можете користуватися бібліотекою penlight . Це функція для розділення рядка за допомогою роздільника, який виводить список.
Він реалізував багато функцій, які нам можуть знадобитися під час програмування та відсутності в Lua.
Ось зразок для його використання.
>
> stringx = require "pl.stringx"
>
> str = "welcome to the world of lua"
>
> arr = stringx.split(str, " ")
>
> arr
{welcome,to,the,world,of,lua}
>
Супер пізно з цим питанням, але у випадку, якщо хтось захоче версії, яка обробляє кількість розщеплень, ви хочете отримати .....
-- 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 = 1
local s, e, cap = str:find(fpat, 1)
while s do
if s ~= 1 or cap ~= "" then
table.insert(t, cap)
end
last_end = e+1
s, e, cap = str:find(fpat, last_end)
if limit ~= nil and limit <= #t then
break
end
end
if last_end <= #str then
cap = str:sub(last_end)
table.insert(t, cap)
end
return t
end
Якщо ви програмуєте в Луа, вам тут не пощастило. Lua - Єдина мова програмування, яка, як відомо, є сумно відомою, оскільки її автори ніколи не реалізовували "розділену" функцію в стандартній бібліотеці, а натомість написали 16 скриншотів пояснень та кульгавих виправдань, чому вони цього не зробили, а що ні, переплетені з численними напівробочими прикладами, які практично гарантовано працюють майже для всіх, але впадають у ваш кутовий випадок. Це просто сучасний стан Луа, і кожен, хто програмує в Луї, просто закінчує стискати зуби і перебирати символи. Існує безліч рішень, які часом кращі, але точно нульові рішення, які надійно кращі.