Я бы просто не использовал gmatch
для этого вообще.
local input = " this is a string (containg some (well, many) annoying) parentheses and should be split. The string contains double spaces. What should be done? And what about trailing spaces? "
local pos = 1
local words = {}
local last_start = pos
while pos <= #input do
local char = string.byte(input, pos)
if char == string.byte(" ") then
table.insert(words, string.sub(input, last_start, pos - 1))
last_start = pos + 1
elseif char == string.byte("(") then
local depth = 1
while depth ~= 0 and pos + 1 < #input do
local char = string.byte(input, pos + 1)
if char == string.byte(")") then
depth = depth - 1
elseif char == string.byte("(") then
depth = depth + 1
end
pos = pos + 1
end
end
pos = pos + 1
end
table.insert(words, string.sub(input, last_start))
for k, v in pairs(words) do
print(k, "'" .. v .. "'")
end
Выход:
1 ''
2 'this'
3 'is'
4 'a'
5 'string'
6 '(containg some (well, many) annoying)'
7 'parentheses'
8 'and'
9 'should'
10 'be'
11 'split.'
12 'The'
13 'string'
14 'contains'
15 ''
16 'double'
17 ''
18 ''
19 'spaces.'
20 'What'
21 'should'
22 'be'
23 'done?'
24 'And'
25 'what'
26 'about'
27 'trailing'
28 'spaces?'
29 ''
Думая о пробелах и других подобных проблемах, мы оставляем читателю упражнение Я попытался выделить некоторые из возможных проблем с примером, который я использовал. Кроме того, я рассмотрел только один вид скобок, так как я не хочу думать, как this (string} should be ]parsed
.
Да, и если вложенные скобки не имеют значения: большую часть кода выше можно заменить вызовом string.find(input, ")", pos, true)
, чтобы найти закрывающую скобку.
Обратите внимание, что вы не можете использовать шаблоны or
или and
, как это делается в вашем коде.
"%(" or "%["
равно "%("
Луа будет интерпретировать это выражение слева направо. "%(
- это истинное значение, Lua уменьшит выражение до "%("
, что логически совпадает с полным выражением.
Так что string.find(i,'%('or'%['or'%{')
найдет только (
в i
.