LINUX.ORG.RU

Lua: паттерн для разделения строки

 ,


0

2

тег awesome тут притом, что не все подписаны на тег lua

имеем строку: 34 ~ olo tlolo ~ mew' olo ~ kkk g! ~ 10:701

нужно её разделить средствами Lua по определённому признаку — в данном случае по ~ (тильда, обёрнутая пробелами), но не по любому другому символу.

я использовал string.gmatch(), но успеха не добился.

я подобрал самое ближайшее по смыслу — ([%w%s]*[^%s~]*), он разделяет строку, опуская ~ , но делит он её и по другим символам ('!:), не отбрасывая их. мне нужно получить ряд строк 34, olo tlolo, mew' olo, kkk g!, 10:701.

есть идеи?

★★★

Последнее исправление: cetjs2 (всего исправлений: 1)

Ответ на: комментарий от funeralismatic

ну первый аргумент — строка, второй — разделитель (в твоём случае '~'), вернет таблицу из строк между разделителем

actionless ★★★★★
()

вариант ([%w%s]*[^%~]*) делает лучше, но так же пишет пустые строки.

частично решает проблему.

funeralismatic ★★★
() автор топика
Ответ на: комментарий от actionless

у меня разделитель не просто тильда, а тильда, обёрнутая в пробелы. это важно, ибо иначе все строки, кроме первой, будут начинаться с пробела, а это не есть гут.

я бы не хотел подключать дополнительные модули, хочется обойтись как можно меньшим объёмом кода, а лучше, чтобы он был мне понятен. (=

funeralismatic ★★★
() автор топика
Ответ на: комментарий от funeralismatic

ну так не подключай его, а просто скопируй код функции, там 6 строчек, одна из них декоративная причем :-)

actionless ★★★★★
()
Ответ на: комментарий от funeralismatic

просто передавай как разделитель " ~", должно работать так:

string_helpers.split("34 ~ olo tlolo ~ mew' olo ~ kkk g! ~ 10:701", " ~")

{ "34", "olo", "tlolo", "mew'", "olo", "kkk", "g!", "10:701" }

actionless ★★★★★
()
Последнее исправление: actionless (всего исправлений: 1)
Ответ на: комментарий от actionless

должно работать так:

{ "34", "olo", "tlolo", "mew'", "olo", "kkk", "g!", "10:701" }

мне не надо так, мне надо вот так:

{ "34", "olo tlolo", "mew' olo", "kkk g!", "10:701" }

funeralismatic ★★★
() автор топика

Делай split по регексу. В каком-нибудь Ruby можно было бы сделать так:

[1] pry(main)> "34 ~ olo tlolo ~ mew' olo ~ kkk g! ~ 10:701".split /\s*~\s*/
=> ["34", "olo tlolo", "mew' olo", "kkk g!", "10:701"]
[2] pry(main)> 
theNamelessOne ★★★★★
()
Ответ на: комментарий от theNamelessOne

со сплитом не вышло, да и такой комбайн явно будет оверхедом, ибо мне нужно строки в массив сунуть.

есть основной массив, в нём на каждую такую строку будет создаваться массив, а уже в нём будут строковые, они нужны в другой функции.

funeralismatic ★★★
() автор топика
Ответ на: комментарий от funeralismatic

со сплитом не вышло, да и такой комбайн явно будет оверхедом

Что значит «не вышло»? В Lua какие-то другие регулярные выражения?

Почему оверхед?

theNamelessOne ★★★★★
()
Ответ на: комментарий от theNamelessOne

В Lua какие-то другие регулярные выражения?

да, там не posix и не perl, а огрызок голимый

actionless ★★★★★
()
Ответ на: комментарий от funeralismatic

Паттерны имеют функицонал куда более узкий, чем регулярки, так что в одно действие, насколько я помню, не получится. Если только так:

#!/usr/bin/lua

function foo(str, symbol)
	
	local result = {}
	
	for i in str:gmatch("(.-)"..symbol) do
		table.insert(result, i)
	end
	
	for i in str:gmatch(".+"..symbol.."(.-)$") do
		table.insert(result, i)
	end
	
	return result
end

for i, v in pairs(foo(arg[1], arg[2])) do
	print(v)
end
[xxblx@localhost Разное]$ ./script.lua "34 ~ olo tlolo ~ mew' olo ~ kkk g! ~ 10:701" "~"
34 
 olo tlolo 
 mew' olo 
 kkk g! 
 10:701
xxblx ★★★
()
Ответ на: комментарий от theNamelessOne

Что значит «не вышло»? В Lua какие-то другие регулярные выражения?

Во-первых, да, другие, во вторых, там нет split в стандартной библиотеке.

ТС, мне некогда сейчас специально для тебя кодить, но я бы посоветовал написать свою реализацию split.

proud_anon ★★★★★
()
Последнее исправление: proud_anon (всего исправлений: 1)
Ответ на: комментарий от proud_anon

Всё-таки накодил. СЛЕГКА ИСПРАВИЛ ПОСЛЕ ПУБЛИКАЦИИ.

function straightforward_split(str, separator)
	local separator, fields, start, i = separator or ",", {}, 1, 1
	while true do
		i = str:find(separator, start, true)
		if i then
			fields[#fields + 1] = str:sub(start, i - 1)
			start = i + #separator
		elseif start < #str then
			fields[#fields + 1] = str:sub(start)
			break
		else
			break
		end
	end
	return fields
end

t = straightforward_split("34 ~ olo tlolo ~ mew' olo ~ kkk g! ~ 10:701", " ~ ")
for k, v in pairs(t) do
	print(v .. ';') -- Чтобы узнать, нет ли лишних пробелов
end

Выводит:

34;
olo tlolo;
mew' olo;
kkk g!;
10:701;

proud_anon ★★★★★
()
Последнее исправление: proud_anon (всего исправлений: 1)
Ответ на: комментарий от actionless

хм, действительно, всё оказалось проще, чем я пытался накостылять.

благодарю за.

funeralismatic ★★★
() автор топика
Ответ на: комментарий от actionless

s:gsub(" *([^~]+) *", function(c) print(c) end)

Да, и в самом деле всё проще.

proud_anon ★★★★★
()
Ответ на: комментарий от actionless

По-моему, задача в том, чтобы ТС понял, в развернутую портянку он явно вникнет быстрей, чем в однострок.

Хотя, конечно, для практического применения и я бы предпочел однострок.

з.ы. а где сказано, что пробелы надо опустить? вроде же ТС просил по ~ как по разделителю строку разрубить.

xxblx ★★★
()
Ответ на: комментарий от xxblx

з.ы. а где сказано, что пробелы надо опустить? вроде же ТС просил по ~ как по разделителю строку разрубить.

(тильда, обёрнутая пробелами)

соответственно, в начале строки не может быть пробелов, так как тот должен обрезаться вместе с тильдой.

По-моему, задача в том, чтобы ТС понял, в развернутую портянку он явно вникнет быстрей, чем в однострок.

никогда не любил документацию, в которой много пустого трёпа, и всегда уважал справочники (в т.ч. доки, генерируемые LDoc) за максимальную информативность в сжатом объёме. а портянки читать — время впустую, ящитаю.

funeralismatic ★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.