Old 01-09-2020, 11:17 AM   #1
dsyrock
Human being with feelings
 
dsyrock's Avatar
 
Join Date: Sep 2018
Location: China
Posts: 229
Default Lua question: How to use string.match with a string contain a "-"

Code:
a='#1|1-1.wav#'

path='1-1.wav'

b=a:match('#(%d+)|'..path)
The value of b should be 1, but I got a nil value. Only if I change "1-1" to "11" then b finally gets the correct number.

So what is the correct way to use string.match in this case?

I found a similar question here: https://forum.cockos.com/showthread....t=string.match

But in my case, path could be variable, sometimes it contains a dash sometimes it doesn't.

Last edited by dsyrock; 01-09-2020 at 11:45 AM.
dsyrock is online now   Reply With Quote
Old 01-09-2020, 11:34 AM   #2
cfillion
Human being with feelings
 
cfillion's Avatar
 
Join Date: May 2015
Location: Québec, Canada
Posts: 2,983
Default

- is the metacharacter for 0 or more repetitions (non-greedy) in Lua patterns. Escape it (add a % before) to mean a literal hyphen.

The dot is also a metacharacter (it accepts any one character). It should be escaped too for matching a literal dot.

Last edited by cfillion; 01-09-2020 at 11:40 AM.
cfillion is offline   Reply With Quote
Old 01-09-2020, 11:36 AM   #3
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,530
Default

Since the string is interpreted as a pattern, you have to escape any of the special pattern-matching characters with %:
Code:
path = "1%-1.wav"
Lokasenna is offline   Reply With Quote
Old 01-09-2020, 12:19 PM   #4
dsyrock
Human being with feelings
 
dsyrock's Avatar
 
Join Date: Sep 2018
Location: China
Posts: 229
Default

Quote:
Originally Posted by cfillion View Post
- is the metacharacter for 0 or more repetitions (non-greedy) in Lua patterns. Escape it (add a % before) to mean a literal hyphen.

The dot is also a metacharacter (it accepts any one character). It should be escaped too for matching a literal dot.
But in my case, the value of path is from a media item, how can i change it to the prober format?
dsyrock is online now   Reply With Quote
Old 01-09-2020, 12:46 PM   #5
cfillion
Human being with feelings
 
cfillion's Avatar
 
Join Date: May 2015
Location: Québec, Canada
Posts: 2,983
Default

Either search/replace each occurrence of a Lua pattern matacharacter to escape them (eg. using string.gsub) or find another way that doesn't involve using string.match with an arbitrary string. What is the root problem/feature this is intended to solve?
cfillion is offline   Reply With Quote
Old 01-09-2020, 12:54 PM   #6
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,530
Default

Code:
local function escapePercent(str) 
  return str:gsub("%-", "%%-") 
end

b = a:match("#(%d+)|" .. escapePercent(path))
You can chain :gsub as many times as you want with the same logic to escape any other special characters.
Lokasenna is offline   Reply With Quote
Old 01-09-2020, 05:09 PM   #7
dsyrock
Human being with feelings
 
dsyrock's Avatar
 
Join Date: Sep 2018
Location: China
Posts: 229
Default

Quote:
Originally Posted by cfillion View Post
Either search/replace each occurrence of a Lua pattern matacharacter to escape them (eg. using string.gsub) or find another way that doesn't involve using string.match with an arbitrary string. What is the root problem/feature this is intended to solve?
Thanks!
dsyrock is online now   Reply With Quote
Old 01-09-2020, 05:12 PM   #8
dsyrock
Human being with feelings
 
dsyrock's Avatar
 
Join Date: Sep 2018
Location: China
Posts: 229
Default

Quote:
Originally Posted by Lokasenna View Post
Code:
local function escapePercent(str) 
  return str:gsub("%-", "%%-") 
end

b = a:match("#(%d+)|" .. escapePercent(path))
You can chain :gsub as many times as you want with the same logic to escape any other special characters.
It works, thanks! By the way, I did something similar before
Code:
path=path:gsub('-', '%-')
Then I realize that is not allowed. Now you showed me the right way.
dsyrock is online now   Reply With Quote
Old 01-09-2020, 07:29 PM   #9
dsyrock
Human being with feelings
 
dsyrock's Avatar
 
Join Date: Sep 2018
Location: China
Posts: 229
Default

Then one more question. For instance, there are stringA and stringB, and stringB is a completely random string. If I'm gonna do something like stringA:match(stringB), do I have to replace all the magic characters in stringB for safety?

Code:
function escape(text)
    text=text:gsub('%-', '%%-')
    text=text:gsub('%.', '%%.')
    etc

    return text
end

stringA:match(escape(stringB))
dsyrock is online now   Reply With Quote
Old 01-09-2020, 07:37 PM   #10
cfillion
Human being with feelings
 
cfillion's Avatar
 
Join Date: May 2015
Location: Québec, Canada
Posts: 2,983
Default

If all you need is checking whether stringA contains stringB, string.find has a "plain" parameter which entirely disables pattern matching when set to true:

Code:
stringA:find(stringB, 1, true) -- no need to escape stringB
cfillion is offline   Reply With Quote
Old 01-09-2020, 08:18 PM   #11
dsyrock
Human being with feelings
 
dsyrock's Avatar
 
Join Date: Sep 2018
Location: China
Posts: 229
Default

Quote:
Originally Posted by cfillion View Post
If all you need is checking whether stringA contains stringB, string.find has a "plain" parameter which entirely disables pattern matching when set to true:

Code:
stringA:find(stringB, 1, true) -- no need to escape stringB
Thanks, but I do need the match function, as the example I post at #1. It would be better if string.match has a plain mode.
dsyrock is online now   Reply With Quote
Old 01-10-2020, 07:33 AM   #12
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,530
Default

string.match doesn't have a plain option, so if you specifically need match you'll have to run string B through the escape function above.
Lokasenna is offline   Reply With Quote
Old 01-12-2020, 07:59 AM   #13
mespotine
Human being with feelings
 
mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig, Germany
Posts: 1,782
Default

Is there a function floating in this forum somewhere, where the escaping of a magic characters in such a string can be made?
So the resulting string can be used for plain-matching? I think, it would be a nice addition for my API.
__________________
Ultraschall-API - a Lua-functions-library4Reaper: https://forum.cockos.com/showthread....98#post2067798
Reaper Internals - Developerdocs4Reaper: https://forum.cockos.com/showthread.php?t=207635
mespotine is offline   Reply With Quote
Old 01-12-2020, 08:21 AM   #14
cfillion
Human being with feelings
 
cfillion's Avatar
 
Join Date: May 2015
Location: Québec, Canada
Posts: 2,983
Default

http://stackoverflow.com/a/34953646
cfillion is offline   Reply With Quote
Old 01-12-2020, 08:36 AM   #15
mespotine
Human being with feelings
 
mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig, Germany
Posts: 1,782
Default

Thanks
__________________
Ultraschall-API - a Lua-functions-library4Reaper: https://forum.cockos.com/showthread....98#post2067798
Reaper Internals - Developerdocs4Reaper: https://forum.cockos.com/showthread.php?t=207635
mespotine is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 03:05 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2020, vBulletin Solutions Inc.