Search code examples
javascriptregexgoogle-apps-script

String.replace(/\s/g,"") deletes one of the characters when the string contains at least 2 % signs separated by only whitespace


I encountered this weird bug while working on an internal library for my work. We use App Script which is based on Javascript. However, there is a weird quirk with the string.replace() function that is causing problems.

Managers often include spaces when sending commands to our email bot so we have a function in a library which removes whitespace. It is:

function cleanSpaces(string){
  return string.replace(/\s/g,"")
}

This function works fine unless the string has at least 2 ampersands separated by at least 1 whitespace character and no other characters.

This is a problem because some of the commands sent to the email bot use special characters, including %s to encode data for the request. Inconsistent behaviors when processing the data could cause problems long term, and I don't know if this bug affects any other special characters.

For testing, I made a function in apps script and a dummy html page. The apps script test function has the following code (with 'testString' replaced with the test string):

function myFunction() {
  let string = 'testString'
  Logger.log(cleanSpaces(testString))
}

And the html document has the following code (with 'testString' replaced with the test string):

<html><body>
<p id="test"></p>

<script>
let string = 'testString';
string = string.replace(/\s/g,"");
document.getElementById("testString").innerHTML = string;
</script>

</body></html>

When the string is set to something like 'Hello World', both functions correctly output HelloWorld

When the string is set to something like ' % 4 %4% 4%', both functions correctly output %4%4%4%

However, when the string is set to something like '% %', the html document correctly outputs %% but the Apps Script incorrectly outputs %.

Could someone please let me know why this happens and what (if anything) can be done to fix it.


Solution

  • The problem occurs in the Execution Logs when the string is printed.

    Instead of printing the values to the Execution Logs, write them elsewhere. In the example below, write the values for the script properties.

    function cleanSpaces(string) {
      return string.replace(/\s/g, "")
    }
    
    function test() {
      ['% %'].forEach(str => {
        const result = cleanSpaces(str);
        PropertiesService.getScriptProperties().setProperty('RESULT' , result);
      });
    }
    

    Instead of using the script properties you might find it more convenient to write the results of your cleanSpaces function to a spreadsheet or a text file in an actual project.