文档中的部分替换仅匹配并保留格式

时间:2017-02-18 05:46:23

标签: google-apps-script google-docs

我们假设我们在google document

中有第一段
  

Wo1rd so2me 字he3re last。

我们需要search and replace文本的某些部分,但必须在版本历史中突出显示,只需,就像我们只更改了这些部分和我们不得忽略我们的格式(粗体,斜体,颜色等)。

我在那一刻所拥有/理解的内容:capturing groups无法在replaceText()中使用,如文档中所述。我们可以使用纯js replace(),但它只能用于字符串。我们的google文档是对象数组,而不是字符串。所以我做了很多尝试并停在那个代码上,稍后附在此消息中。

无法击败:我如何才能取代我发现的部分内容。捕获组是非常强大和合适的工具,但我不能用它来替换。他们没有工作或我可以替换整个段落,这是不可接受的,因为版本历史将显示完整段落替换和段落将失去格式。如果我们搜索的内容会出现在每个段落中,但只有一个字母必须更改,该怎么办?我们将在历史中看到完整的文档替换,很难找到真正改变的内容。

我的第一个想法是比较字符串,replace()给我带有段落的内容然后比较符号后的符号并替换不同的东西,但我明白,只有当我们确定只有一个字母时它才会起作用改变。但是如果替换会删除/添加一些单词,如何同步呢?这将是一个更大的问题。

我发现并阅读三次的所有主题都没有帮助,也没有让我摆脱死胡同。

那么,有什么想法可以解决这个问题吗?

function RegExp_test() {
  var docParagraphs = DocumentApp.getActiveDocument().getBody().getParagraphs();
  var i = 0, text0, text1, test1, re, rt, count;

  // equivalent of .asText() ???
  text0 = docParagraphs[i].editAsText();  // obj
  // equivalent of .editAsText().getText(), .asText().getText()
  text1 = docParagraphs[i].getText();     // str

  if (text1 !== '') {
    re = new RegExp(/(?:([Ww]o)\d(rd))|(?:([Ss]o)\d(me))|(?:([Hh]e)\d(re))/g);  // v1
//    re = new RegExp(/(?:([Ww]o)\d(rd))/);         // v2

    count = (text1.match(re) || []).length;       // re v1: 7, re v2: 3

    if (count) {
      test1 = text1.match(re);   // v1: ["Wo1rd", "Wo", "rd", , , , , ]
//      for (var j = 0; j < count; j++) {
//        test1 = text1.match(re)[j];
//      }

      text0.replaceText("(?:([Ww]o)\\d(rd))", '\1-A-\2');   // GAS func
      // #1: \1, \2 etc - didn't work: " -A- word so2me word he3re last."
      test1 = text0.getText();

      // js func, text2 OK: "Wo1rd word so-B-me word he3re last.", just in memory now
      text1 = text1.replace(/(?:([Ss]o)\d(me))/, '$1-B-$2'); // working with str, not obj
      // rt OK: "Wo1rd word so-B-me word he-C-re last."
      rt = text1.replace(/(?:([Hh]e)\d(re))/, '$1-C-$2');

      // #2: we used capturing groups ok, but replaced whole line and lost all formatting
      text0.replaceText(".*", rt);
      test1 = text0.getText();
    }
  }
  Logger.log('Test finished')
}

1 个答案:

答案 0 :(得分:1)

找到解决方案。它足够原始,但它可以作为更复杂程序的基础,可以修复所有出现的捕获组,检测它们,混合它们等等。如果有人想改进它 - 欢迎你!

function replaceTextCG(text0, re, to) {
  var res, pos_f, pos_l;
  var matches = text0.getText().match(re);
  var count = (matches || []).length;

  to = to.replace(/(\$\d+)/g, ',$1,').replace(/^,/, '').replace(/,$/, '').split(",");
  for (var i = 0; i < count; i++) {
    res = re.exec(text0.getText())
    for (var j = 1; j < res.length - 1; j++) {
      pos_f = res.index + res[j].length;
      pos_l = re.lastIndex - res[j + 1].length - 1;
      text0.deleteText(pos_f, pos_l);
      text0.insertText(pos_f, to[1]);
    }
  }
  return count;
}

function RegExp_test() {
  var docParagraphs = DocumentApp.getActiveDocument().getBody().getParagraphs();
  var i = 0, text0, count;

  // equivalent of .asText() ???
  text0 = docParagraphs[i].editAsText();  // obj
  if (text0.getText() !== '') {
    count = replaceTextCG(text0, /(?:([Ww]o)\d(rd))/g, '$1A$2');
    count = replaceTextCG(text0, /(?:([Ss]o)\d(me))/g, '$1B$2');
    count = replaceTextCG(text0, /(?:([Hh]e)\d(re))/g, '$1C$2');
  }
  Logger.log('Test finished')
}