2017-01-20 4 views
2

Я все еще привык к понятию строковых шаблонов, и у меня возникла проблема с ними. Я пытаюсь создать простую программу, которая ищет строку текста, для определенных символов, заключенных в любые скобки. Вот пример:Как создать шаблон строки в Lua, чтобы найти инкапсулированный текст, похожий на уценку?

local str = "Hello <<world>>, my <<name>> is <<John>>" 

-- Match patterns with <<...>> 
for noun in str:gmatch("<<.->>") do 
    print(noun) 
end 

Эта программа будет искать через строку, соответствие все, что начинается с << и заканчивается >>, и все между ними. Хорошо, вот что я хочу. Однако, скажем, мне нужен другой шаблон, который получил только текст между одним из этих тегов вместо двух (< и > вместо << и >>). Здесь я столкнулся с проблемой:

-- Allow easy customization control over brackets 
local matchNouns = {"<<", ">>"} 
local matchOther = {"<", ">"} 

local str = "<Hello> <<world>>, <my> <<name>> <is> <<John>>" 

local function printOtherMatches(str) 
    -- Get opening and closing brackets 
    local open, close = unpack(matchOther) 

    -- Concatenate opening and closing brackets with 
    -- pattern for finding all characters in between them 
    for other in str:gmatch(open .. ".-" .. close) do 
     print(other) 
    end 
end 

printOtherMatches(str) 

Программа выше будет печати все между < и >matchOther элементах), однако он также печатает текст захватил с << и >>, а также. I только хочу, чтобы итератор возвращал шаблоны, которые явно соответствуют открывающим и закрывающим тегам. Таким образом, выход из выше должен напечатать:

<Hello>

<my>

<is>

Вместо:

<Hello>

<<world>>

<my>

<<name>>

<is>

<<John>>

В принципе, так же, как с уценкой, как вы можете использовать * и ** для различных форматов, я хотел бы создать шаблон строки для этого в Lua. Это была моя попытка подражать такой последовательности шаблонов. Если у кого-то есть какие-то идеи или понимание того, как я мог бы это достичь, я бы очень признателен!

+0

Не уверен, но, возможно, пограничный шаблон, что вам нужно: 'местный matchOther = {"% е [<] <% е [^ <]", "%f[>]> % f [^>] "}', проверьте https://ideone.com/Wf2QQS. –

+0

Работает ли он так, как ожидалось, или вы считаете, что это не соответствует сценарию? –

+0

Да, это на самом деле. Я не знал о магическом персонаже% f, но я буду экспериментировать с ним. – user7385467

ответ

0
-- Allow easy customization control over brackets 
local matchNouns = {"<<", ">>"} 
local matchOther = {"<", ">"} 
local delimiter_symbols = "<>" -- Gather all the symbols from all possible delimiters above 

local function printMatches(str, match_open_close) 
    -- Get opening and closing brackets 
    local open, close = unpack(match_open_close) 
    -- Concatenate opening and closing brackets with 
    -- pattern for finding all characters in between them 
    for other in str:gmatch(
     "%f["..delimiter_symbols:gsub("%p", "%%%0").."]" 
     ..open:gsub("%p", "%%%0") 
     .."%f[^"..delimiter_symbols:gsub("%p", "%%%0").."]" 
     .."(.-)" 
     .."%f["..delimiter_symbols:gsub("%p", "%%%0").."]" 
     ..close:gsub("%p", "%%%0") 
     .."%f[^"..delimiter_symbols:gsub("%p", "%%%0").."]" 
    ) do 
     print(other) 
    end 
end 

local str = "<Hello> <<world>>, <my> <<name>> <is> <<John>>" 
printMatches(str, matchOther) 
0

Вот одна возможность:

local s = '<Hello> <<world>>, <my> <<name>> <is> <<John>>' 

for s in s:gmatch '%b<>' do 
    if not s:sub(2,-2):match '%b<>' then print(s) end 
end 
+0

На самом деле, он правильно подбирается, так как '% b <>' подсчитывает количество разделителей открытия и закрытия. (Б означает «сбалансированный») – tonypdmtr

+0

Действительно. Извини . –