Шаблоны Lua для замены нескольких точек с запятой

Я получил эту строку в сценарии Lua:

one;two;;three;four;;five;;six;seven;

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

Использование шаблонов Lua (и string.gsub()): Как можно сопоставить двойные точки с запятой в середине, чтобы заменить их на одну и удалить последнюю необязательную точку с запятой?

Вывод должен быть таким:

one;two;three;four;five;six;seven

Возможно ли это с помощью одного шаблона?

5 ответов

Решение

Использование одного шаблона для замены нескольких ; в одиночку ;и еще один убрать последний ; это так

local str = "one;two;;three;four;;five;;six;seven;"
local result = str:gsub(';+', ';'):gsub(';*$', '')

Один из возможных способов использования одного шаблона:

local result = (str .. ";;;"):gsub(";+", function(s) 
                                             if s == ";" or s == ";;" then 
                                                 return ";" 
                                             else 
                                                 return "" 
                                             end 
                                         end)

Что я пытаюсь сделать, это добавить три ; до конца строки, так что любой один или два ; должен быть заменен одним ;, И больше ;(может быть три или четыре, и это должно быть в конце) заменяется пустой строкой.

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

Как насчет чего-то вроде этого:

function remove_extra_delim(s, delim)
    local t = {}
    for each in s:gmatch("[^"..delim.."]+") do
        table.insert(t, each)
    end
    return table.concat(t, delim)
end

teststr = "one;two;;three;four;;five;;six;seven;"
print(remove_extra_delim(teststr, ";"))

Выходы:

один два три четыре пять шесть семь

Это немного странно, но делает свое дело:

x = test:gsub(";+(.?)",
  function(a)
    if a == "" then
      return ""
    else
      return ";" .. a
    end
  end)

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

string:gsub(";;", ";")

В противном случае подойдут другие ответы.

(Примечание: я точно следую вашему описанию, поэтому они будут соответствовать одному или двум; но не более чем двум, и конечному нулю или одному; но не более чем одному)

-- Method one uses two patterns but it's simpler and my preferred one
s = 'one;two;;three;four;;five;;six;seven;'
s = s:gsub(';;',';'):gsub(';?$','')
print(s)

-- Method two uses one pattern (if you really MUST use only one pattern)
s = 'one;two;;three;four;;five;;six;seven;'
s = (s..';'):gsub(';;',';')
s = s:sub(1,#s-1)
print(s)
Другие вопросы по тегам