Search code examples
stringluagsublua-patterns

A pattern to match until "::" not working with string.gsub


I'm trying to match any if statement ending with ::, and replace it with 'if (condition) then'.

For example:

if (x) ::  

should be replaced with

if (x) then

I'm using string.gsub to achieve this, but it seems that my pattern isn't correct. The following code only matches one if statement, but I want it to match all of them.

local code = [[

    if (x) ::

    end

    if (y) ::

    end

]]

print(code:gsub("(if.+)::", "%1 then"))

--[[
  what I wanted:

  if (x) then

  end

  if (y) then

  end



  what I got:

  if (x) ::

  end

  if (y) then

  end
]]

I'm not sure what I'm doing wrong. Can anyone help?


Solution

  • Use code:gsub("(if.-)::", "%1 then"); note the use of - instead of + as it makes the repetition "non-greedy" and it will capture the smallest number of "any character". .+ in the original pattern matches everything to the end of the line and then backtracks until it finds ::, but it only finds the last one; that's why you only get one replacement.

    Using (if.-):: generates the output you expect:

    if (x)  then
    
    end
    
    if (y)  then
    
    end