【问题标题】:How to replace numbered list elements with an identifier containing the number如何用包含数字的标识符替换编号列表元素
【发布时间】:2020-08-23 20:53:26
【问题描述】:

我今天在这里得到了惊人的帮助!

我正在尝试做其他事情。我在 Google 文档中有一个编号的问题列表,我想将这些数字替换为其他内容。

例如,我想替换列表中的数字,例如:

  1. 地球在一年中的哪个月份离太阳最近? ~七月 ~六月 =一月 ~三月 ~九月

  2. 在澳大利亚(南半球),什么时候白天最短,夜晚最长? ~12月下旬 ~ 三月下旬 =六月下旬 ~四月下旬 ~在澳大利亚,白天和黑夜的长度几乎相同

与:

::Q09:: 地球在一年中的哪个月离太阳最近? ~七月 ~六月 =一月 ~三月 ~九月

::Q11:: 在澳大利亚(南半球),什么时候白天最短,夜晚最长? ~12月下旬 ~ 三月下旬 =六月下旬 ~四月下旬 ~在澳大利亚,白天和黑夜的长度几乎相同

我已经尝试使用以前帖子中的建议,但只提出了以下内容,这似乎不起作用。

感谢您的光临!!!

function questionName2(){
  var body = DocumentApp.getActiveDocument().getBody();
  var text = body.editAsText();
    var pattern = "^[1-9]";
    var found = body.findText(pattern);
    var matchPosition = found.getStartOffset();
  
  while(found){
    text.insertText(matchPosition,'::Q0');
    found = body.findText(pattern, found);
  }
}

【问题讨论】:

  • 我试过了,但也没有用:function questionName3() { var body = DocumentApp.getActiveDocument().getBody(); var i = 1; while(i<9){ body.replaceText("^\\s*\i\\.\\s*", "::Q0\i::"); i++; } }
  • 试试这样的? var doc = DocumentApp.getActiveDocument(); var body = doc.getBody();变量 i = 1;变量重新编号;而 (i
  • 如果想将Google Document中列表的默认项目符号(1. 2. ,,,)修改为自定义项目符号(::Q01:: ::Q02:: ,,,),可惜现阶段无法通过脚本实现和 API。在 API 中,只能检索自定义项目符号。但是,从你的问题来看,我无法理解你的情况和目标的细节。因此,如果您没有从默认项目符号修改为自定义项目符号,则可能会提出解决方案和/或解决方法。这个怎么样?顺便说一句,在您的示例中,为什么910 分别是::Q09::::Q11::
  • 谢谢两位。下面的答案奏效了!

标签: google-apps-script google-docs


【解决方案1】:

正则表达式

Text.findText(searchPattern) 使用一个字符串,该字符串将使用 Google 的 RE2 library 解析为 regular expression 用于 searchPattern。以这种方式使用字符串需要在从字符中删除特殊含义时添加一个额外的反斜杠,例如匹配问题编号后的句点,或者使用像 \d 这样的字符匹配集作为数字。

^\\s*\\d+?\\. 将匹配一组数字,任何非零长度,以任何长度(包括零)的前导空格开始一行。 \d 用于数字,+ 是一个或多个,+? 的组合使匹配变得懒惰。这里不需要懒惰的部分,但我的习惯是默认懒惰以避免错误。另一种方法是 \d{1,2} 专门匹配 1 到 2 位数字。

要从匹配的文本中仅提取数字,我们可以使用 JavaScript RegExp 对象。与 Doc 正则表达式不同,此正则表达式不需要额外的反斜杠,并且允许我们使用带括号的捕获组。

^\s*(\d+?)\. 与上面几乎相同,除了没有多余的斜杠,我们现在将“保存”数字,以便我们可以在替换字符串中使用它们。我们使用括号标记我们想要保存的内容。因为这将是一个普通的 JavaScript 正则表达式文字,所以我们将整个内容用斜杠括起来:/^\s*(\d+?)\./,但开头和结尾 / 只是表示这是一个正则表达式文字。

文本元素和文本字符串

Text.findText 可以返回的不仅仅是我们要求的完全匹配:它返回包含文本的整个元素以及正则表达式匹配的索引。为了使用捕获组执行搜索和替换,我们必须使用索引删除旧文本,然后插入新文本。

以下赋值为我们提供了进行搜索和替换所需的所有数据:首先是元素,然后是开始和停止索引,最后使用 slice 提取匹配的文本字符串(注意 slice 使用独占端,而 Doc API 使用 包含端,因此是 +1)。

var found = DocumentApp.getActiveDocument().getBody().findText(pattern);
var matchStart = found.getStartOffset();
var matchEnd = found.getEndOffsetInclusive();
var matchElement = found.getElement().asText();
var matchText = matchElement.getText().slice(matchStart, matchEnd + 1);

注意事项

正如 Tanaike 在 cmets 中指出的那样,这假定编号不是自动生成数字的 List Items,而是您手动输入的数字。如果您使用的是自动生成的数字列表,API 不允许您编辑编号格式。

此答案还假设在示例中,当您映射“9”时。到“::Q09::”和“10”。到“::Q11::”,10 到 11 的映射是一个错字。如果这是有意为之,请更新问题以阐明编号可能会更改的规则。

还假设数字应该小于 100,给定示例“Q09”的零填充。该示例应该足够灵活,以便您可以根据需要将其更新为不同的填充方案。

完整示例

由于该问题未使用任何 V8 功能,因此假设为较旧的 Rhino 环境。

/**
 * Replaces "1." with "::Q01::"
 */
function updateQuestionNumbering(){
  var text = DocumentApp.getActiveDocument().getBody();
  var pattern = "^\\s*\\d+?\\.";
  var found = text.findText(pattern);
  while(found){
    var matchStart = found.getStartOffset();
    var matchEnd = found.getEndOffsetInclusive();
    var matchElement = found.getElement().asText();
    var matchText = matchElement.getText().slice(matchStart, matchEnd + 1);
    matchElement.deleteText(matchStart, matchEnd);
    matchElement.insertText(matchStart, matchText.replace(/^\s*(\d+?)\./, replacer));  
    found = text.findText(pattern, found);
  }
  
  /**
   * @param {string} _ - full match (ignored)
   * @param {string} number - the sequence of digits matched
   */
  function replacer(_, number) {
    return "::Q" + padStart(number, 2, "0") + "::";
  }
  
  // use String.prototype.padStart() in V8 environment
  // above usage would become `number.padStart(2, "0")`
  function padStart(string, targetLength, padString) {
    while (string.length < targetLength) string = padString + string;
    return string;
  }
}

【讨论】:

  • dwmorrin,再次非常感谢您!这很好用,我自己永远也想不通。在编写可能对我有用的 Google 脚本时,是否有简单的手册或“howto”?带有函数和示例列表的东西?我自己一直找不到东西,而且我很难寻求帮助!
  • @EllenSiem - google-apps-script 标签的策展人创建了一个很棒的resource list here, on SO。这个“用捕获组搜索和替换”是 Apps Script API 的一个特别古怪的角落,所以不用担心需要帮助。我建议您深入简单地学习通用 JavaScript,然后您将能够理解 official Google documentation 以及这里的其他任何人。
猜你喜欢
  • 2021-11-26
  • 2014-02-15
  • 1970-01-01
  • 1970-01-01
  • 2016-04-09
  • 1970-01-01
  • 2015-11-30
  • 2019-08-24
  • 1970-01-01
相关资源
最近更新 更多