Search code examples
stringlualua-patterns

Why doesn't this match non-greedily and give me just the image name?


local s = "http://example.com/image.jpg"
print(string.match(s, "/(.-)%.jpg"))

This gives me

--> /example.com/image

But I'd like to get

--> image

Solution

  • Since the regex engine processes a string from left to right, your pattern found the first /, then .- matched any chars (.) as few as possible (-) up to the first literal . (matched with %.) followed with jpg substring.

    enter image description here

    You need to use a negated character class [^/] (to match any char but /) rather than . that matches any character:

    local s = "http://example.com/image.jpg"
    print(string.match(s, "/([^/]+)%.jpg"))
    -- => image
    

    See the online Lua demo

    The [^/] matches any chars but /, thus, the last / will be matched with the first / in the pattern "/([^/]+)%.jpg". And it will match as

    enter image description here

    Removing the first / from the pattern is not a good idea as it will make the engine use more redundant steps while trying to find a match, / will "anchor" the quantified subpattern at the / symbol. It is easier for the engine to find a / than look for 0+ (undefined from the beginning) number of chars other than /.

    If you are sure this string appears at the end of the string, add $ at the end of the pattern (it is not clear actually if you need that, but might be best in the general case).