What's wrong with my string.gsub()?

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

What's wrong with my string.gsub()?

Steve Litt
Hi all,

Here's a nonworking mock-up of code to implement Prompted Argument
Substitution in my UMENU program. In the string str, things of the form
%x%prompt%% should trigger a prompt for the user to type in information which
replaces the thing of the form %x%prompt%%. The UMENU specifications demand
that all prompts be presented to the user in sort order, not in the order they
appear in the command. So I first insert them all in the words array, then
sort the words array so they are presented in sorted order, then present them
as prompts so the user can type in the information, and on each, I do a
string.gsub() to replace that prompt with the user's response. Unfortunately
it doesn't work and I have no idea why.

=================================
str = "mycommand %c%Carg please=>%% %b%Barg please=>%% %a%Aarg please=>%%
final args"

words = {}
        for w in string.gfind(str, "%%.%%.-%%%%") do
                table.insert(words, w)
        end

table.sort(words, function (a, b)
        return string.lower(a) < string.lower(b)
end)

io.write("B4 , str=>"); print(str)
for k,v in ipairs(words, k) do
        local temp = string.gsub(v, "%%.%%", "")
        local response
        local junk = str
        temp = string.gsub(temp, "%%%%", "")
        io.write(temp)
        response = io.read()
        print(v)
        print(response)
        str = string.gsub(str, v, response)
        --str = string.gsub(str, tostring(v), response,1)
        print(str)
end
io.write("Aft, str=>"); print(str)
=================================
Here's a session:

******************************************
slitt@mydesk:~/ulua/program$ ./test.lua
B4 , str=>mycommand %c%Carg please=>%% %b%Barg please=>%% %a%Aarg please=>%%
final args
Aarg please=>al
%a%Aarg please=>%%
al
mycommand %c%Carg please=>%% %b%Barg please=>%% %a%Aarg please=>%% final args
Barg please=>ben
%b%Barg please=>%%
ben
mycommand %c%Carg please=>%% %bben% %a%Aarg please=>%% final args
Carg please=>cim
%c%Carg please=>%%
cim
mycommand %c%Carg please=>%% %bben% %a%Aarg please=>%% final args
Aft, str=>mycommand %c%Carg please=>%% %bben% %a%Aarg please=>%% final args
slitt@mydesk:~/ulua/program$
******************************************

Everything works until the final string.gsub(), and that fails to substitute
on A and C, and substitutes in an odd manner on B. Anyone see what I'm doing
wrong?

Thanks

SteveT

Steve Litt
Recession Relief Package
http://www.recession-relief.US
Twitter: http://www.twitter.com/stevelitt


Reply | Threaded
Open this post in threaded view
|

Re: What's wrong with my string.gsub()?

KHMan
On 1/3/2011 9:21 AM, Steve Litt wrote:

> [snip]
> str = string.gsub(str, v, response)
>
> ******************************************
> slitt@mydesk:~/ulua/program$ ./test.lua
> B4 , str=>mycommand %c%Carg please=>%% %b%Barg please=>%% %a%Aarg please=>%%
> final args
> Aarg please=>al
> %a%Aarg please=>%%
> al

v = "%a%Aarg please=>%%"
response = "al"

string.gsub() wants a pattern for the second operand. But you want
to use v as a literal. So you need to escape those "%" (and
perhaps other magic characters) and make gsub interpret v as a
literal.

"%a%Aarg please=>%%" => "%%a%%Aarg please=>%%%%" (I think)

--
Cheers,
Kein-Hong Man (esq.)
Kuala Lumpur, Malaysia

Reply | Threaded
Open this post in threaded view
|

Re: What's wrong with my string.gsub()? <SOLVED>

Steve Litt
Kein-Hong Man's solution worked. His solution was to escape the percent signs
in the pattern. More at the end of this email...

On Sunday 02 January 2011 20:40:11 KHMan wrote:

> On 1/3/2011 9:21 AM, Steve Litt wrote:
> > [snip]
> > str = string.gsub(str, v, response)
> >
> > ******************************************
> > slitt@mydesk:~/ulua/program$ ./test.lua
> > B4 , str=>mycommand %c%Carg please=>%% %b%Barg please=>%% %a%Aarg
> > please=>%% final args
> > Aarg please=>al
> > %a%Aarg please=>%%
> > al
>
> v = "%a%Aarg please=>%%"
> response = "al"
>
> string.gsub() wants a pattern for the second operand. But you want
> to use v as a literal. So you need to escape those "%" (and
> perhaps other magic characters) and make gsub interpret v as a
> literal.
>
> "%a%Aarg please=>%%" => "%%a%%Aarg please=>%%%%" (I think)
>

Kein-Hong Man, you were right. For some reason I figured if the pattern was in
variable then it didn't have to be escaped, but of course this is wrong. So I
added and used a function called string2pattern, as shown below:

=======================================
function string2pattern(str)
        return string.gsub(str, "%%", "%%%%")
end

str = "mycommand %c%Carg please=>%% %b%Barg please=>%% %a%Aarg please=>%%
final args"

local words = {}
local w
for w in string.gfind(str, "%%.%%.-%%%%") do
        table.insert(words, w)
end

table.sort(words, function (a, b)
        return string.lower(a) < string.lower(b)
end)

io.write("B4 , str=>"); print(str)
local k,v
for k,v in ipairs(words, k) do
        local temp = string.gsub(v, "%%.%%", "")
        temp = string.gsub(temp, "%%%%", "")
        io.write(temp)
        local response = io.read()
        str = string.gsub(str, string2pattern(v), response)
end
io.write("Aft, str=>"); print(str)
=======================================

Here's the session:

*********************************
slitt@mydesk:~/ulua/program$ ./test.lua
B4 , str=>mycommand %c%Carg please=>%% %b%Barg please=>%% %a%Aarg please=>%%
final args
Aarg please=>al
Barg please=>ben
Carg please=>cim
Aft, str=>mycommand cim ben al final args
slitt@mydesk:~/ulua/program$
*********************************

Obviously for a more robust program I'd need string2pattern() to escape more
characters than just the percent sign, but for the purposes of UMENU what I've
done should be enough.

I might tighten it up a little bit so as not to disturb single percent signs.

Thanks

SteveT

Steve Litt
Recession Relief Package
http://www.recession-relief.US
Twitter: http://www.twitter.com/stevelitt


Reply | Threaded
Open this post in threaded view
|

Re: What's wrong with my string.gsub()?

Alexander Gladysh
In reply to this post by KHMan
On Mon, Jan 3, 2011 at 04:40, KHMan <[hidden email]> wrote:
> On 1/3/2011 9:21 AM, Steve Litt wrote:

> string.gsub() wants a pattern for the second operand. But you want to use v
> as a literal. So you need to escape those "%" (and perhaps other magic
> characters) and make gsub interpret v as a literal.

> "%a%Aarg please=>%%" => "%%a%%Aarg please=>%%%%" (I think)

This function may be useful:

https://github.com/lua-nucleo/lua-nucleo/blob/master/lua-nucleo/string.lua#L137-158

(I think that may actually be a reuse of some code on Lua-Users.)

Alexander.

Reply | Threaded
Open this post in threaded view
|

Re: What's wrong with my string.gsub()? <SOLVED>

Dirk Laurie
In reply to this post by Steve Litt
On Mon, Jan 03, 2011 at 04:05:58AM +0200, Steve Litt wrote:
> Kein-Hong Man's solution worked. His solution was to escape the percent signs
> in the pattern. More at the end of this email...
There's some good stuff in Section 20.6 "Tricks of the Trade" in the
String Library chapter of PiL2.  I reread it once every week :-)

Dirk

Reply | Threaded
Open this post in threaded view
|

Re: What's wrong with my string.gsub()? <SOLVED>

Daurnimator
In reply to this post by Steve Litt
On 3 January 2011 02:05, Steve Litt <[hidden email]> wrote:

> Kein-Hong Man, you were right. For some reason I figured if the pattern was in
> variable then it didn't have to be escaped, but of course this is wrong. So I
> added and used a function called string2pattern, as shown below:
>
> =======================================
> function string2pattern(str)
>        return string.gsub(str, "%%", "%%%%")
> end
> *********************************
>
> Obviously for a more robust program I'd need string2pattern() to escape more
> characters than just the percent sign, but for the purposes of UMENU what I've
> done should be enough.
>
> I might tighten it up a little bit so as not to disturb single percent signs.
>
> Thanks
>
> SteveT

You'll want to change \0 to %z, otherwise I can't think of any other
problems off the top of my head....

Daurn.