Pregunta

Tengo esta cadena en un script de lua:

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

El primer char nunca será un punto y coma. Los separadores intermedios pueden ser un semicolon único o doble, y el último char puede ser o no un solo semicolon.

Usando los patrones de lua (y string.gsub()): ¿Cómo puedo hacer coincidir las semicolones dobles en el medio para reemplazarlos con uno solo y eliminar el último semicolon opcional?

La salida debe ser así:

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

¿Es esto posible usar un solo patrón?

¿Fue útil?

Solución

Usando un patrón para reemplazar múltiples ; a soltero ;, y otro para eliminar el último ; es así

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

Una posible forma de usar un solo patrón es como esta:

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

Lo que estoy tratando de hacer es agregar tres ; al final de la cadena, por lo que cualquiera o dos ; debe ser reemplazado por uno ;. Y más ;(podría ser tres o cuatro y debe ser al final) se reemplaza a una cadena vacía.

Preferiría la solución con dos patrones, ya que es más claro.

Otros consejos

Qué tal algo como esto:

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

Salidas:

uno dos tres CUATRO CINCO SEIS SIETE

Si la cantidad de semicolones es 1 o 2, simplemente puede hacerlo

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

De lo contrario, las otras respuestas servirán.

Es un poco hacky, pero hace el truco:

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

(Nota: sigo tu descripción exactamente, por lo que estos coincidirán con uno o dos; pero no más de dos, y cero final o uno; pero no más de uno)

-- 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)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top