Google 用于在正文中查找 URL 并将其格式化为超链接的 Apps 脚本

Google Apps Script to find URLs in body and format them as hyperlinks

我有一段由命令行脚本生成的文本块,它启动了多个虚拟机。文本输出包含有关如何访问虚拟机上的 Web 应用程序的说明,例如:

TrainingMachine01
Username: [user] 
Password: [pass] 
iPython: http://ip/ 
RStudio: http://ip:8787/

我将此文本转储到 Google 文档中,该文档与许多人共享(我们 运行 在 Python 和 R 中开设课程,并启动虚拟机每位与会者)。

我希望能够将我的输出格式化为 hyperlinks,这样与会者只需单击 URL,而不是将其复制并粘贴到浏览器中(第一世界的问题)。

在研究了将文本粘贴到 Google 文档中的方法之后,我认为没有比 Google Apps 脚本更简单的解决方案了,它可以简单地找到匹配 URL 的模式, 并使它们成为 hyperlinks.

这是我到目前为止的内容,主要基于 this answer 另一个问题:

function updateLinks() {
  // Open active doc
  var body = DocumentApp.getActiveDocument().getBody();
  // Find URLs
  var link = body.findText("http:\/\/.*\/");

  // Loop through
  while (link != null) {
    // Get the link as an object
    var foundLink = link.getElement().asText();

    // Get the positions of start and end
    var start = link.getStartOffset();
    var end =link.getEndOffsetInclusive();

    // Format link
    foundLink.setLinkUrl(start, end, foundLink);

    // Find next
    link = body.findText("http:\/\/.*\/", link);
  }
}

我的模式和循环工作正常,除了写入 hyperlink 的 URL 是 http://text 如果我在格式 foundLink 中使用=48=] 部分,或者 http://rangeelement 如果我使用 link 变量。

如何让脚本将 URL 设置为文本本身?

(Javascript 的新手,一直在使用这样的练习来学习它和 Google Apps 脚本)

更新: a-change 的评论将我指向文本元素上的 getText() 方法,因此相关行变为 foundLink.setLinkUrl(start, end, foundLink.getText());。然而,这仍然不是很有效,并且正在插入指向 about:blank 的 links。关于如何清理从 findText() 中提取的文本的任何想法?

更详细地研究了它。 如果您记录 foundLink.getText() 的值,您会看到它实际上包含在该行找到的所有字符串,即 RStudio: http://ip:8787/ 而不仅仅是 http://ip:8787/。这可能是因为 link.getElement() returns 包含找到的文本的范围的整个元素。

您可以将所有 link 写在不同的行上,该函数可以很好地工作,但文档本身可能看起来不太好。

所以你需要在这里做的是另外将 link 从 foundLink.getText() 字符串中切出。这是稍作修改的初始函数:

 function updateLinks() {
  // Open active doc
  var body = DocumentApp.getActiveDocument().getBody();
  // Find URLs
  //Logger.log(body.findText("http").getElement().asText().getText());
  var link = body.findText("http:\/\/.*\/");
  // Loop through
  while (link != null) {
    // Get the link as an object
    var foundLink = link.getElement().asText();
    // Get the positions of start and end
    var start = link.getStartOffset();
    var end = link.getEndOffsetInclusive();
    //check the value of foundLink if needed
    //Logger.log(foundLink.getText());
    //slice only the link out of it
    var correctLink = foundLink.getText().slice(start, end);
    // Format link
    foundLink.setLinkUrl(start, end, correctLink);
    // Find next
    link = body.findText("http:\/\/.*\/", link);
  }
}

我已经尝试了上面和其他地方的其他正则表达式示例,但在重现结果时遇到了问题 - 我怀疑是因为 Google Apps 脚本不是完整的 JS。

这对我有用,可以检测带有尾随空格的 http 和 https 链接。我测试了 start/end 在 line/para 末尾的链接以及前面和后面的测试(由空格分隔),它们都有效。

function makeLinks() {
  var linkRegex = "https?:\/\/[^\s]*";

  // Open active doc
  var body = DocumentApp.getActiveDocument().getBody();
  // Find URLs
  //Logger.log(body.findText("http").getElement().asText().getText());
  var link = body.findText(linkRegex);

  // Loop through the body finding texts matching the search pattern
  while (link != null) {
    // Get the link as an object
    var linkElement = link.getElement().asText();
    // Get the positions of start and end
    var start = link.getStartOffset();
    var end = link.getEndOffsetInclusive();

    //slice only the link out of it
    var correctLink = linkElement.getText().slice(start, end);
//    Logger.log("correctLink " + correctLink);

    // Format link
    linkElement.setLinkUrl(start, end, correctLink);
    // Find next
    link = body.findText(linkRegex, link);
  }
}

希望对其他人有所帮助