2015-02-22 3 views
6

Так что я следующий код, чтобы разделить строку между непечатаемых:Lua: разбить строку на слова, если не цитировал

text = "I am 'the text'" 
for string in text:gmatch("%S+") do 
    print(string) 
end 

Результат:

I 
am 
'the 
text' 

Но мне нужно сделать это:

I 
am 
the text --[[yep, without the quotes]] 

Как это сделать?

Редактировать: только в дополнение к вопросу, идея состоит в передаче параметров из программы в другую программу. Вот запрос на перенос, который я работаю в настоящее время: https://github.com/mpv-player/mpv/pull/1619

ответ

6

Могут быть способы сделать это с помощью умного разбора, но альтернативным способом может быть отслеживание простого состояния и слияния фрагментов на основе обнаружения цитируемые фрагменты. Нечто подобное может работать:

local text = [[I "am" 'the text' and "some more text with '" and "escaped \" text"]] 
local spat, epat, buf, quoted = [=[^(['"])]=], [=[(['"])$]=] 
for str in text:gmatch("%S+") do 
    local squoted = str:match(spat) 
    local equoted = str:match(epat) 
    local escaped = str:match([=[(\*)['"]$]=]) 
    if squoted and not quoted and not equoted then 
    buf, quoted = str, squoted 
    elseif buf and equoted == quoted and #escaped % 2 == 0 then 
    str, buf, quoted = buf .. ' ' .. str, nil, nil 
    elseif buf then 
    buf = buf .. ' ' .. str 
    end 
    if not buf then print((str:gsub(spat,""):gsub(epat,""))) end 
end 
if buf then print("Missing matching quote for "..buf) end 

Это будет печатать:

I 
am 
the text 
and 
some more text with ' 
and 
escaped \" text 

Обновлено для обработки смешанных и кавычки экранированы. Обновлено для удаления кавычек. Обновлено для обработки цитируемых слов.

+0

Я предпочел бы что-то с помощью строки синтаксического анализа. В любом случае, пока я не сказал в сообщении, мне нужно что-то работать как с одиночными, так и с двойными кавычками, так как идея этого кода заключается в анализе параметров из оболочки. – m45t3r

+0

Это легко обновить это решение, чтобы заставить его работать с одинарными и двойными кавычками; просто замените ''^'' '' на [[^ ["']]] и' '' $" 'на' [[[''] $]] '. Вам также может потребоваться проверить, что вступительная цитата соответствует закрывающей. –

+0

Это можно сделать с помощью синтаксического анализа строк, но решение, вероятно, будет более сложным (а не с одним выражением, поскольку шаблоны Lua недостаточно мощны, чтобы выразить то, что вам нужно). –

1

Попробуйте это:

text = [[I am 'the text' and '' here is "another text in quotes" and this is the end]] 

local e = 0 
while true do 
    local b = e+1 
    b = text:find("%S",b) 
    if b==nil then break end 
    if text:sub(b,b)=="'" then 
     e = text:find("'",b+1) 
     b = b+1 
    elseif text:sub(b,b)=='"' then 
     e = text:find('"',b+1) 
     b = b+1 
    else 
     e = text:find("%s",b+1) 
    end 
    if e==nil then e=#text+1 end 
    print("["..text:sub(b,e-1).."]") 
end 
+0

Исправлено для обработки как одиночных, так и двойных кавычек, а также пустой цитируемый текст. – lhf

1

Lua Шаблоны не являются мощными, чтобы справиться с этой задачей правильно. Вот решение LPeg, адаптированное из Lua Lexer. Он обрабатывает как одиночные, так и двойные кавычки.

local lpeg = require 'lpeg' 

local P, S, C, Cc, Ct = lpeg.P, lpeg.S, lpeg.C, lpeg.Cc, lpeg.Ct 

local function token(id, patt) return Ct(Cc(id) * C(patt)) end 

local singleq = P "'" * ((1 - S "'\r\n\f\\") + (P '\\' * 1))^0 * "'" 
local doubleq = P '"' * ((1 - S '"\r\n\f\\') + (P '\\' * 1))^0 * '"' 

local white = token('whitespace', S('\r\n\f\t ')^1) 
local word = token('word', (1 - S("' \r\n\f\t\""))^1) 

local string = token('string', singleq + doubleq) 

local tokens = Ct((string + white + word)^0) 


input = [["This is a string" 'another string' these are words]] 
for _, tok in ipairs(lpeg.match(tokens, input)) do 
    if tok[1] ~= "whitespace" then 
    if tok[1] == "string" then 
     print(tok[2]:sub(2,-2)) -- cut off quotes 
    else 
     print(tok[2]) 
    end 
    end 
end 

Выход:

This is a string 
another string 
these 
are 
words 

 Смежные вопросы

  • Нет связанных вопросов^_^