0

I have a bit of code that is searching a document for a tag and replacing it with a specific merge field. This code works fine until my tag has a | (pipe symbol) in it.

For some reason that makes the search only partially match. I suspect this has something to do with it thinking the variable I am passing is a regEx pattern and not a literal string, but I am unsure how to force it to be treated as a string. I use replaceText, which accepts regex as a string.

bodyObject.replaceText(Regex<String>, Replacement<String>);

I use it like this:

bodyObject.replaceText(markup, dataRow[headerIndex]);

In the above example markup that equals "{{ tag | directive }}" would cause the partially match.

TheMaster
  • 45,448
  • 6
  • 62
  • 85
user10012
  • 647
  • 1
  • 8
  • 23
  • Can you just escape all pipes in markup? – Cooper Oct 29 '21 at 19:36
  • Well evidently your current regex is a hack if it's not working the way you want. – Cooper Oct 29 '21 at 19:56
  • Is it an option to escape the whole string @user10012? This would work on yours, no need overwriting or modifying the variable `markup`, just escape it once you pass it as parameter. It will look like this `bodyObject.replaceText(markup.replace(/\W/g, "\\$&"), dataRow[headerIndex]);` – NightEye Oct 29 '21 at 20:22
  • 1
    That did work! Can you elaborate as to what that did exactly? I get you just taking everything not considered a word, but I am unclear as to why the multiple \\ and the other characters. – user10012 Oct 29 '21 at 20:33
  • I posted the same as answer below. Included the reference. @user10012. – NightEye Oct 29 '21 at 20:39

2 Answers2

1

.replaceText() supports and re2 supports \Q...\E:

\Q...\E literal text ... even if ... has punctuation

So you can use:

bodyObject.replaceText(String.raw`\Q${markup}\E`, dataRow[headerIndex]);

This will treat everything inside \Q...\E as literal characters.

TheMaster
  • 45,448
  • 6
  • 62
  • 85
0

If we are expecting the markup to be plain text, you can just escape the whole variable when it is passed as a parameter in replaceText. I don't find this breaking anything you have and you won't modify anything else aside from the replaceText line.

Sample:

function escapeString() {
  var bodyObject = DocumentApp.getActiveDocument().getBody();
  
  markup = "{{ tag | directive }}";
  
  newString = "<mergeField>";
  // escape any non word character ($& = whole matched string)
  bodyObject.replaceText(markup.replace(/\W/g, "\\$&"), newString);
}

Before:

sample

After:

after

Reference:

NightEye
  • 10,634
  • 2
  • 5
  • 24