4

With Lua's string.find function, there is an optional fourth argument you can pass to enable plain searching. From the Lua wiki:

The pattern argument also allows more complex searches. See the PatternsTutorial for more information. We can turn off the pattern matching feature by using the optional fourth argument plain. plain takes a boolean value and must be preceeded by index. E.g.,

= string.find("Hello Lua user", "%su")         -- find a space character followed by "u"

10      11

= string.find("Hello Lua user", "%su", 1, true) -- turn on plain searches, now not found

nil

Basically, I was wondering how I can accomplish the same plain searching using Lua's string.gsub function.

5
  • If you don't mind me asking, why are you trying to use gsub for something it wasn't at all meant for? Commented Apr 8, 2015 at 0:22
  • I'm trying to replace large chunks of a string with another string. Commented Apr 8, 2015 at 0:23
  • Oh, I made that comment assuming that there was a plaintext search-replace function already existing in the string library, but reading through the docs I'm not so sure it's there Commented Apr 8, 2015 at 0:25
  • I'm pretty sure there isn't :( Commented Apr 8, 2015 at 0:26
  • 1
    Escape every non-alphanumeric character in your search string. Commented Apr 8, 2015 at 0:34

3 Answers 3

3

I expected there to be something in the standard library for this, but there isn't. The solution, then, is to escape the special characters in the pattern so they don't perform their usual functions.

Here's the general idea:

  1. obtain the pattern string
  2. replace any special characters with % followed by it (for example, % becomes %%, [ becomes %[
  3. use this as your search pattern for replacing the text
Sign up to request clarification or add additional context in comments.

2 Comments

the simplest implementation would be: pattern:gsub( '%W', function(x) return '%'..x end )
@hjpotter92, or pattern:gsub('%W','%%%1) though %p would probably suffice instead of %W.
2

Here is a simple library function for text replacement:

function string.replace(text, old, new)
  local b,e = text:find(old,1,true)
  if b==nil then
     return text
  else
     return text:sub(1,b-1) .. new .. text:sub(e+1)
  end
end

This function can be called as newtext = text:replace(old,new).

Note that this only replaces the first occurrence of old in text.

1 Comment

Since OP wants gsub for plain text, it should be return text:sub(1,b-1) .. new .. text:sub(e+1):replace(old, new)
2

Use this function to escape all magic characters (and only those) in your search string.

function escape_magic(s)
  return (s:gsub('[%^%$%(%)%%%.%[%]%*%+%-%?]','%%%1'))
end

1 Comment

There is no capture group in your pattern, therefore in the replacement string, %0 (whole match) should be used instead of %1 (first capture, which doesn't exist here). However, I have just tried the code (on Lua 5.1), and when there is no capture group, %1 contains the whole match, exactly as %0. Though, I wouldn't rely on this surprising (and undocumented) behavior, and use the proper %0.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.