Trying to replace string with "\" (backslash)

I am submitting information using network.request and GET

\_G.theNetworkRequest = network.request( requestString, "GET", serverCommunicate.networkListener,params );

the requestString could look like this: https:\www.somewhere.com?description=mytext

The requestString contains information entered by the user, and I need to find a way to handle special characters that are not causing the request string to be malformed.

if the description, instead of “mytext” contains characters like  ^  or , the URL is malformed.

Therefore I replace these characters with e.g. “-!!!BACKSLASH!!!-” and when read the data that is returned from the server I want to replace “-!!!BACKSLASH!!!-” with “” again.

The problem is the string.gsub() function.

Here is my code: 

 theDescription = "some text -!!!BACKSLASH!!!- and some more text" local lookfor = "-!!!BACKSLASH!!!-"; local replacewith = '\\'; theDescription = string.gsub(theDescription,lookfor,replacewith);
  • One problem is that theDescription after this substitution contains the text:

“some text \!- and some more text”

in other words, the gsub() functions does not replace the whole string, but leaves “!-” at the end of it.

(I have tried replacewith = “%\”, but it gives the same result)

  • The other problem is that I cannot set the variable replacewith = “” (or “%”), because then the IDE (ZeroBrane Studios) tells me that “” is an unfinished string and will not comply the code.

It’ll be easier to just use mime.
 

local mime = require("mime") local string = "/^s.-!%)\\'" print(string) -- output: /^s.-!%)\' string = mime.b64(string) print(string) -- output: L15zLi0hJSlcJw== string = mime.unb64(string) print(string) -- output: /^s.-!%)\'

Using mime’s base64 encoding and decoding you can make any string safe to submit in a URL. All you need to do is encode at source, send and decode at destination.

you can change the text you replace with a text that gsub works, for example:

local theDescription = “some text ####BACKSLASH#### and some more text”

    

local lookfor = “####BACKSLASH####”;

    local replacewith = ‘\’;

    theDescription = string.gsub(theDescription,lookfor,replacewith);

print (theDescription)

Sorry carloscosta

theDescription = "some text -###BACKSLASH###- and some more text" local lookfor = "-###BACKSLASH###-"; local replacewith = '\\'; theDescription = string.gsub(theDescription,lookfor,replacewith); print(" theDescription: "..theDescription)

gives this:

– Output:  theDescription: some text \#- and some more text

Am I missing something?  :huh:

If your issue is with URL strings becoming malformed, all you need to do is use base64 encoding with them as in my sample code above. You don’t need to play around with gsub or anything.

Thank XeduR, do you have an example on how to encode it using PHP 7.2 so that I can store the data in the MySQL database ?

They are directly available in the manual.

https://www.php.net/manual/en/function.base64-encode.php

https://www.php.net/manual/en/function.base64-decode.php

Thanks, again XeduR,

I have managed to implement the decode in the App and the encode on the PHP on the Server.

But, I still have a problem with the bakslash ().

If I enter e.g. "abc " into a native.NewTextField() and read the value

local theValue = theCustomerDescriptionField.text -- abc \ print(theValue) -- output: abc \\

Ah, yeah. Those occur because backlashes are used to escape characters in Lua. I’m guessing that your string is automatically “fixed” for you somewhere since you can’t actually have a string like "abc " in Lua because it would be an unfinished string.

So, if you have string like “abc \” it will appear as "abc " if you output it, but you can’t actually turn it into "abc " because it just won’t work (unfinished string again). You could, if you want, change the “\” into “/” by looping through the entire string, character by character. Do you have a specific need to do this?
 

Just to sum up again what my problem is: 

I enter “abc\test” into an entryfield. Looking at the value of the entry field, it has changed to “abc\test”

I try to replace a single “”, but Corona or ZeroBrane requires that I escape the character, so I replace it as follows.

 lookfor = '\\'; replacewith = "-!!!BACKSLASH!!!-" theString = string.gsub(theString,lookfor,replacewith); print theString -- output: abc-!!!BACKSLASH!!!-test

When I try to read the information back (from the MySQL database) I try to do the reverse:

 local lookfor= "-!!!BACKSLASH!!!-" local replacewith = '\\'; theDescription = string.gsub(theDescription,lookfor,replacewith); print theDescription -- output: abc\\!-test

the “print” function shows two backslashes (but in the entryField it is shown as one)

However, the problem now is that the string.gsub() does not remove the complete text, “!-” is still left after the replace has been done.

The need for this is an app where the user should be able to enter any character into textfields and these should be saved in the database and later shown in the App and on a website.

I have already decided to filter out the single ^-character, and I have to replace the Eurosign (€) since it cannot be saved in the database when I use PHP.

The reason as to why “abc\test” from your entryfield changes to “abc\test” is because a lone backslash cannot exist in a lua string. It will always break the string. The function that you are using is adding the extra backslash there to prevent the string from being broken.

i.e. if a user inputs a string “abc\test” it will be stored as “abc\test”, but if you later create a display object with that, the display object will still read as “abc\test”.

I would personally just prevent the users from submitting any such special characters. This will usually save you a lot of time and money from needing to worry about these issues. Unless there is a specific need to allow the user to type in those characters, you can filter them out by using something like “if char:find(”%w") or char == " " then" to check that the newly inputted character is either an alphanumeric character or a space. You could add punctuation there for the checks as well, etc.

It might be a good idea to at least stop the user from entering some difficult characters, but it is hard to know what they all are since the user might be using different national keyboards with very different characters.

I have tried however, to replace the \ with a /, but the textlistener event = “editing” is also having problems 

 local newChar = event.newCharacters local oldText = event.oldText if newChar then if newChar == "\\" then if oldText ~= nil then event.target.text = "/" else event.target.text = oldText.."/" end end end 

When I enter a \ the event.oldText becomes “nil”

(I could maybe remember the event.oldText in a variable, but it shows the problems with the backslash)

Can you compare newChar to the character code for “” rather than a literal string?

Yes, it looks like I have to do that. I am not happy about it since the customer should be able to enter any type of text.

But it looks like I have to implement this code:

-- theEnteredText is set to event.target.text when event.phase == "began"  local newChar = event.newCharacters local oldText = event.oldText if newChar then local theAscii = string.byte(newChar) if theAscii == 92 then if theEnteredText == "" then event.target.text = "/" else event.target.text = theEnteredText.."/" end end end theEnteredText = event.target.text

This might work easier

-- Contruct an URL compatable string from a table of parameters -- @param table params The parameters to be used in {paramName = paramValue, etc} format. local urlOperations = require("socket.url") local urlEncode = urlOperations.escape function paramsToString(params) local paramsString = "" for name, value in pairs(params) do if value then value = urlEncode(tostring(value)) if string.len(value) \> 0 then -- No empty values are to be sent paramsString = paramsString .. name .. "=" .. value .. "&" end end end return paramsString end

I took a few minutes to adjust the sample code from Corona docs. This is how I’d approach the issue:

[lua] local defaultField local acceptedString, character = "", "" local textObject = display.newText( "", display.contentCenterX, display.contentCenterY-40, system.defaultFont, 32 ) local function textListener( event ) if event.phase == "editing" then acceptedString = "" for i = 1, event.newCharacters:len() do character = event.newCharacters:sub(i,i) if character:find( "%w") or character == " " then -- %w is alphanumeric characters acceptedString = acceptedString..character end end textObject.text = acceptedString end end defaultField = native.newTextField( display.contentCenterX, display.contentCenterY, 180, 30 ) defaultField.inputType = "no-emoji" defaultField:addEventListener( "userInput", textListener ) [/lua]

This way, you’d loop through the string whenever new characters are entered. In the loop, you’d only accept alphanumeric characters and spaces. If you want to accept or reject some other types of characters or specific characters, you can just add them to the check (for character classes, see https://www.lua.org/pil/20.2.html). Alternatively, you could just watch out for things that you definitely don’t want and block those out.

Thank you all. I will try to implement it to avoid characters that cause problems.

Just use URL escaping (code I posted above) and then you do not have to worry about user entry at all. 

Simple :slight_smile:

Why did you add “-” next to the “###” in my example i didn’t put it for a reason it will not work with gsub, but this is the worst implementation ever. I just gave you an example how to resolve your problem changing 1 char.if you copy paste my example it will work.