Вопрос

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

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

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

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

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

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

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

Это было полезно?

Решение

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

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, ";"))

Выходы:

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

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

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

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

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

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

(ПРИМЕЧАНИЕ: я точно следую вашему описанию, поэтому они будут соответствовать одному или двум; но не более двух, и окончательный нулевой или один; но не более одного)

-- 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)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top