Qwert Yuiop
Qwert Yuiop

Reputation: 170

What Lua pattern behaves like a regex negative lookahead?

my problem is I need to write a Lua code to interpret a text file and match lines with a pattern like

if line_str:match(myPattern) then do myAction(arg) end

Let's say I want a pattern to match lines containing "hello" in any context except one containing "hello world". I found that in regex, what I want is called negative lookahead, and you would write it like

.*hello (?!world).*

but I'm struggling to find the Lua version of this.

Upvotes: 1

Views: 853

Answers (1)

Luatic
Luatic

Reputation: 11201

Let's say I want a pattern to match lines containing "hello" in any context except one containing "hello world".

As Wiktor has correctly pointed out, the simplest way to write this would be line:find"hello" and not line:find"hello world" (you can use both find and match here, but find is probably more performant; you can also turn off pattern matching for find).


I found that in regex, what I want is called negative lookahead, and you would write it like .*hello (?!world).*

That's incorrect. If you checked against the existence of such a match, all it would tell you would be that there exists a "hello" which is not followed by a "world". The string hello hello world would match this, despite containing "hello world".

Negative lookahead is a questionable feature anyways as it isn't trivially provided by actually regular expressions and thus may not be implemented in linear time.

If you really need it, look into LPeg; negative lookahead is implemented as pattern1 - pattern2 there.

Finally, the RegEx may be translated to "just Lua" simply by searching for (1) the pattern without the negative part (2) the pattern with the negative part and checking whether there is a match in (1) that is not in (2) simply by counting:

local hello_count = 0; for _ in line:gmatch"hello" do hello_count = hello_count + 1 end
local helloworld_count = 0; for _ in line:gmatch"helloworld" do helloworld_count = helloworld_count + 1 end
if hello_count > helloworld_count then
    -- there is a "hello" not followed by a "world"
end

Upvotes: 0

Related Questions